Spring3 @ExceptionHandler for ServletRequestBindingException

时间:2011-03-01 10:18:10

标签: spring spring-mvc

我正在使用Default AnnotationMethodHandlerAdapter,我相信它应该支持@ExceptionHandler。不幸的是,如果调用下面这样的处理程序方法,则抛出ServletRequestBindingException - 而不是调用Exception处理程序。

@RequestMapping(value = "/v1/products/{code}", method = RequestMethod.GET, headers = "Accept=application/xml,application/json")
@ResponseBody
public ProductDemoDTO getProductByCode(@PathVariable final String code,
        @RequestParam(required = false, defaultValue = "BASIC") final String options)
{
    //omitted
}

这里是ExceptionHandler,从未调用过:

@ExceptionHandler(Throwable.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
//TODO not being called?
public void handleException(final Exception e, final HttpServletRequest request, final Writer writer) throws IOException
{
    writer.write(String.format("{\"error\":{\"java.class\":\"%s\", \"message\":\"%s\"}}", e.getClass(), e.getMessage()));
}

有谁知道为什么没有调用ExceptionHandler?

4 个答案:

答案 0 :(得分:3)

此问题已在Spring 3.2中修复。您可以使用@ControllerAdvice注释创建全局异常处理程序类。然后在该类中添加一个@ExceptionHandler方法来处理ServletRequestBindingException并返回一个自定义响应体。例如:

@ControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(ServletRequestBindingException.class)
  public ResponseEntity<String> handleServletRequestBindingException(ServletRequestBindingException ex)   {
      return new ResponseEntity<String>("MISSING REQUIRED HEADER",HttpStatus.PRECONDITION_REQUIRED);
  }
}

有关更多信息,请查看spring mvc docs:17.11 Handling exceptions

答案 1 :(得分:2)

不幸的是,@ExceptionHandler方法仅针对从处理器方法中的引发的异常进行调用。 ServletRequestBindingException是在尝试调用处理程序方法时抛出的基础结构异常,如果由于某种原因无法调用处理程序方法本身,则不使用@ExceptionHandler

似乎没有更好的方法来处理这个问题。但是,如果不知道是什么导致了ServletRequestBindingException,那么很难建议。

答案 2 :(得分:1)

你无法使用spring自定义实现来处理它。

它可能不是一个优雅的解决方案,但您仍然可以使用web.xml <error-page>标记来捕获它。你可以从这里捕获异常类型或错误代码。

答案 3 :(得分:0)

Aaand感谢 Juergen Hoeller 今天已经解决了这个问题,应该会出现在 Spring 4.3 中。

请参阅问题: https://jira.spring.io/browse/SPR-11106