在春天处理包装异常mvc
我有春天mvc和杰克逊。当我得到不正确的请求时,jackson映射失败并引发UnrecognizedPropertyException。我想处理使用在春天处理包装异常mvc
@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
...
}
但是春天包装此异常HttpMessageConversionException所以上面的代码不起作用此异常。是否有可能在春季处理杰克逊特定(或一般图书馆特定)的例外?
不幸的是,UnrecognizedPropertyException
是IOException
的亚型。处理@RequestBody
(我假设这是发生异常的位置)的RequestResponseBodyMethodProcessor
对IOException
(解释为请求输入流的故障)有特殊处理,将其包装在HttpMessageNotReadableException
中。此外,如果在read
期间存在转换错误,则指定HttpMessageConverter
接口将抛出HttpMessageNotReadableException
。不管怎样(如果杰克逊抛出未经检查的异常,事情可能会有所不同),你将不得不处理这个问题。
幸运的是,since 4.3, Spring MVC's ExceptionHandlerMethodResolver
(其中进程@ExceptionHandler
)可以打开cause
的例外(see SPR-14291)。因此,假设你没有为在HttpMessageNotReadableException
继承层次结构的任何异常处理程序,你的处理方法
@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
...
}
将被用来处理异常。这发生在Spring MVC查找可以处理HttpMessageNotReadableException
的处理程序方法后,然后用Throwable#getCause
解开嵌套的异常并再次尝试查找。
在前期4.3,或者如果你有在HttpMessageNotReadableException
的继承层次的异常类型的处理程序,可以随时提取自己的事业后委派。
@ExceptionHandler
public String handle(HttpMessageConversionException e) throws Throwable {
Throwable cause = e.getCause();
if (cause instanceof UnrecognizedPropertyException) {
handle((UnrecognizedPropertyException) cause);
}
...
}
public String handle(UnrecognizedPropertyException e) {
...
}
我做这种方式:
/**
* Global exception handler for unhandled errors.
* @author Varun Achar
* @since 2.0
* @version 1.0
*
*/
public class Http500ExceptionResolver extends SimpleMappingExceptionResolver
{
@Inject
private ViewResolver resolver;
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
{
ModelAndView mv = new ModelAndView();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
if(CommonUtil.isAjax(request))
{
MappingJackson2JsonView view = new MappingJackson2JsonView();
view.setObjectMapper(JsonUtil.getObjectMapper());
mv.addObject("responseMessage", "We had some problems while serving your request. We are looking into it");
mv.addObject("responseCode", GenericResponse.ERROR.code());
mv.addObject("success", false);
mv.setView(view);
}
else
{
mv.setViewName(resolver.getView(ViewConstants.ERROR_PAGE));
}
return mv;
}
}
而且在我的servlet上下文:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
<property name="order" value="0" />
</bean>
<bean id="securityExceptionResolver"
class="com.trelta.commons.utils.security.SecurityExceptionResolver">
<property name="order" value="1"></property>
<property name="exceptionMappings">
<map>
<entry key="org.springframework.security.access.AccessDeniedException"
value="/common/accessDenied"></entry>
<entry key="org.springframework.security.core.AuthenticationException"
value="/common/authenticationFailure"></entry>
</map>
</property>
</bean>
<bean id="http500ExceptionResolver"
class="com.trelta.commons.utils.security.Http500ExceptionResolver">
<property name="order" value="3" />
</bean>
顺序字段是因为通过上按顺序异常解析器春周期很重要。你也可以为自己定义一个这样的异常映射,你很好走!
检查this博客文章和javadoc为SimpleMappingExceptionResolver
我想我们有误会。问题是我不能这样做'
哦..明白了.. Spring包装了异常,我检查了spring的源代码,除非你重写类的方法,否则你不能这么做。@ Sotirios的方法似乎是最好的 – 2013-03-21 12:07:40
难看,但作品和我有什么好 – piotrek 2013-04-03 12:44:13
@piotrek你确定这个工程?我们已经在Spring 4.2中尝试了这一点,但它没有。 Spring只记录了一条调试消息并抛弃了异常('ExceptionHandlerExceptionResolver'中的'logger.debug(“无法调用@ExceptionHandler方法:”+ exceptionHandlerMethod,invocationEx)') – 2017-01-16 10:45:36
我再也无法访问该代码,对不起: ( – piotrek 2017-01-16 15:39:26