2010-07-12 69 views
28

使用Spring 3创建的ExceptionHandler,我喜欢创造使用的ExceptionHandler标注,将处理请求“发现(404)无页”异常处理程序。我正在使用下面的代码来做到这一点。但是,当我指向一个不存在的URL时,将调用Spring定义的默认异常处理程序。春季3 - 为NoSuchRequestHandlingMethodException

可能是因为我在处理NoSuchRequestHandlingMethodException异常。如果是,那么我应该注册什么样的例外?

请你看看下面的代码,看看我做错了什么?

注:如果我改变例外的@ExceptionHandlerNullPointerException异常,并创建一个RequestMapping抛出空指针,将工作。当对同一类中的@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方法被调用。因此,当你添加映射投掷NullPointerException,那工作,因为映射的方法和异常处理程序在同一个类中。

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

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

+2

谢谢。我将使用HandlerExceptionResolver方法。 – sgsweb 2010-07-12 19:28:26

+0

它适合你吗?我仍然遇到同样的问题 – SJS 2013-03-22 13:16:56

2

你可以用this的方法,这是个好主意和工作方式,只有使用特定的Handler才能抛出异常,这使得@ExceptionHandler不像看起来那么有用。

16

在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); 
    } 
+0

这几乎是我最终做的事情,但是因为我也在使用ContentNegotiatingViewResolver,所以我最终捕获了'Exception',然后用JSON和XML序列化注释将其包装到一个类中,然后返回而不是ModelAndView,所以客户端最终得到了包装对象的序列化版本。 – 2013-02-08 11:58:55