在 Spring 中而不是 Servlet 容器中处理 ServletRequestBindingException 等异常
我正在将 springmvc 用于 REST 项目,每当客户端使用错误的 HTTP 方法调用 REST 资源时,就会抛出 servletrequestbindException。我无法在控制器中使用 @ExceptionHandler 处理这些异常,因为它不是发生在处理程序方法中,而是发生在 spring 映射层中。
目前我声明了一个 web.xml 异常处理,这有效:
<error-page>
<exception-type>org.springframework.web.bind.ServletRequestBindingException</exception-type>
<location>/servletRequestBindingException.jsp</location>
</error-page>
<error-page>
<error-code>405</error-code>
<location>/methodNotSupported.jsp</location>
</error-page>
不过我宁愿使用 spring 异常处理。例如,我想根据传入的 Accept 标头创建动态响应,因此可以为剩余异常写出 json 或 xml。最好的方法是从此处理程序返回一个对象,该对象会自动转换为 json 或 xml,就像从处理程序返回的普通 dto 一样。
有没有办法捕获这些较低级别的映射异常?
I am using springmvc for a REST project and whenever the client calls a rest resource with the wrong HTTP method, a servletrequestbindingexception is thrown. I cannot handle these exceptions with a @ExceptionHandler in the controller, as it happens not within the handler method but in the spring mapping layer.
Currently I declared a web.xml exception handling, this works:
<error-page>
<exception-type>org.springframework.web.bind.ServletRequestBindingException</exception-type>
<location>/servletRequestBindingException.jsp</location>
</error-page>
<error-page>
<error-code>405</error-code>
<location>/methodNotSupported.jsp</location>
</error-page>
I'd rather use spring exception handling though. For example I'd like to create a dynamic response based on teh incoming Accept header, so either writing out json or xml for a rest exception for example. The best would be to return an object from this handler that would automatically be converted to json or xml just like a normal dto returned from a handler.
Is there a way to catch these lower level mapping exceptions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不能使用
@ExceptionHandler
(因为正如您所说,这是为了处理从处理程序代码中抛出的异常),但您仍然可以使用HandlerExceptionResolver
框架 来执行此操作。默认情况下,
DispatcherServlet
注册DefaultHandlerExceptionResolver
的实例:HTTP 405 的生成实际上是在此类中处理的,方法是捕获处理程序映射代码抛出的 HttpRequestMethodNotSupportedException。
因此,如果您想以不同的方式处理此异常,您可以提供您自己的 HandlerExceptionResolver 实现。最简单的方法可能是继承
DefaultHandlerExceptionResolver
并重写handleHttpRequestMethodNotSupported
方法,从那里返回您的ModelAndView
。You can't use
@ExceptionHandler
(since as you say, this is for dealing exceptions thrown from within the handler code), but you can still use theHandlerExceptionResolver
framework to do this.By default,
DispatcherServlet
registers an instance ofDefaultHandlerExceptionResolver
:The generation of the HTTP 405 is actually handled in this class, by catching
HttpRequestMethodNotSupportedException
thrown by the handler-mapping code.So if you want to handle this exception differently, you can provide your own implementation of
HandlerExceptionResolver
. It's probably easiest to subclassDefaultHandlerExceptionResolver
and override thehandleHttpRequestMethodNotSupported
method, returning yourModelAndView
from there.如果您包含自己的异常解析器,请小心包含默认的异常解析器。如果您使用带注释的 @Exception 处理程序,则需要显式加载它们,否则它们将不再起作用。
在这种情况下,FooBarHandlerExceptionResolver 扩展了 DefaultHandlerExceptionResolver 并提供了默认解析器未涵盖的方法。这让 FooBarHandlerExceptionResolver 可以处理我无法使用带注释的 @Exception 处理程序方法捕获的类级异常。
这是异常解析器
Be careful to include the default exception resolvers if you include your own. If you are using annotated @Exception handlers you need to explicitly load these or they will no longer function.
In this case, FooBarHandlerExceptionResolver extends DefaultHandlerExceptionResolver and provides a method that the default resolver doesn't cover. This lets FooBarHandlerExceptionResolver handle class-level exceptions that I couldn't catch with annotated @Exception handler methods.
Here is the exception resolver