Spring 3 - 为 NoSuchRequest 创建 ExceptionHandlerHandlingMethodException

使用Spring 3,我喜欢使用异常处理程序注释创建一个异常处理程序,该注释将处理“未找到页面(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;
      }
    }

答案 1

@ExceptionHandler-带批注的方法在同一类上引发异常时调用。因此,当您添加抛出 的映射时,这有效,因为映射的方法和异常处理程序位于同一类中。@RequestMappingNullPointerException

当找不到映射时,Spring 无法将 与 你的 相关联,因为它没有将请求与处理程序方法进行匹配。这在文档中没有明确提及,但这是我观察到的行为。NoSuchRequestHandlingMethodException@ExceptionHandler

如果你想特别处理这个异常,你将不得不使用更通用的HandlerExceptionResolver方法,而不是更专业的技术。@ExceptionHandler


答案 2

在Spring 3.2中,您可以使用@ContollerAdvice为所有控制器设置一个异常处理程序,如下所示:

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

推荐