Подтвердить что ты не робот

Spring 3 - Создать ExceptionHandler для NoSuchRequestHandlingMethodException

Используя 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;
      }
    }
4b9b3361

Ответ 1

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

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

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

Ответ 2

В 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);
    }

Ответ 3

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