Spring 3 - Создать ExceptionHandler для NoSuchRequestHandlingMethodException - PullRequest
28 голосов
/ 12 июля 2010

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

Возможно, я обрабатываю исключение 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;
      }
    }

Ответы [ 3 ]

41 голосов
/ 12 июля 2010

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

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

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

16 голосов
/ 16 ноября 2012

В Spring 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);
    }
2 голосов
/ 23 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...