2010-07-12 3 views
28

Использования Spring 3, я хотел бы создать обработчик исключений с помощью ExceptionHandler аннотации, которая будет обрабатывать «не найдено страницы (404)» запросов. Для этого я использую следующий код. Но когда я указываю на URL-адрес, который не существует, вызывается обработчик исключений по умолчанию, определенный Spring.Spring 3 - Создание ExceptionHandler для NoSuchRequestHandlingMethodException

Возможно, я обрабатываю исключение исключений NoSuchRequestHandlingMethodException. Если да, то какое исключение я должен регистрировать?

Не могли бы вы взглянуть на следующий код и посмотреть, что я делаю неправильно?

Примечание: Если изменить исключение в @ExceptionHandler к NullPointerException и создать RequestMapping бросить пустой указатель, который будет работать.

import org.springframework.stereotype.Controller; 
    import org.springframework.web.bind.annotation.ExceptionHandler; 
    import org.springframework.web.bind.annotation.RequestMapping; 

    import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; 

    import org.apache.commons.logging.Log; 
    import org.apache.commons.logging.LogFactory; 
    import org.springframework.web.servlet.ModelAndView; 

    @Controller 
    public class GeneralHandler { 
     private final Log logger = LogFactory.getLog(getClass()); 

     @ExceptionHandler(NoSuchRequestHandlingMethodException.class) 
     public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) { 
     ModelAndView mav = new ModelAndView(); 
     logger.error("Exception found: " + ex); 
     return mav; 
     } 
    } 

ответ

41

@ExceptionHandler -annotated методы вызываются, когда @RequestMapping метод на том же классе генерирует исключение. Поэтому, когда вы добавили отображение, которое запустило NullPointerException, это сработало, поскольку сопоставленный метод и обработчик исключений были вместе в одном классе.

Когда сопоставление не найдено, Spring не имеет возможности связать NoSuchRequestHandlingMethodException с вашим @ExceptionHandler, потому что он не дошел до соответствия методу обработчика. Это явно не упоминается в документах, но это поведение, которое я наблюдал.

Если вы хотите обработать это исключение специально, вам придется использовать более общий HandlerExceptionResolver approach, а не более специализированный метод @ExceptionHandler.

+2

спасибо. Я буду использовать подход HandlerExceptionResolver. – sgsweb

+0

Это сработало для вас? У меня все еще такая же проблема. – SJS

2

Вы можете использовать подход this, это отличная идея и работает, необходимость бросать исключения только с определенным обработчиком делает @ExceptionHandler не столь полезным, как кажется.

16

Весной 3.2 вы можете использовать @ContollerAdvice иметь ExceptionHandler для всех контроллеров, как это:

@ControllerAdvice 
public class GeneralHandler { 

    @ExceptionHandler 
    public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) { 
     ModelAndView mav = new ModelAndView(); 
     ... 
     return mav; 
    } 
} 

Вы даже можете добавить больше аннотаций вернуться Сериализированная JSon

@ExceptionHandler 
    @ResponseBody 
    @ResponseStatus(HttpStatus.BAD_REQUEST) 
    public RestError resolveBindingException (MethodArgumentNotValidException methodArgumentNotValidException, Locale locale) 
    { 
     BindingResult bindingResult = methodArgumentNotValidException.getBindingResult(); 
     return getRestError(bindingResult, locale); 
    } 
+0

Это в значительной степени то, что я закончил делать, но так как я также использовал ContentNegotiationViewResolver, я в конечном итоге ловил «Исключение», а затем обертывал это в классе с аннотациями JSON и XML-сериализации и возвращал вместо ModelAndView, поэтому клиент получает сериализованную версию объекта-обертки. –

Смежные вопросы