我有Spring MVC和杰克逊。 当我开始不正确的请求,杰克逊映射失败, UnrecognizedPropertyException
被抛出。 我想用处理此异常
@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
...
}
然而在春包装这个异常HttpMessageConversionException
所以上面的代码不起作用。 是否有可能在春季来处理杰克逊具体的(或一般图书馆专用)异常?
不幸的是, UnrecognizedPropertyException
是一个亚型IOException
。 该RequestResponseBodyMethodProcessor
处理该@RequestBody
(我认为这就是发生异常)具有特殊处理IOException
(如解析请求输入流的失败),在其包装HttpMessageNotReadableException
。 此外,该HttpMessageConverter
接口被指定为抛HttpMessageNotReadableException
如果存在时的转换错误read
。
你将不得不面对,不管什么(如果杰克逊抛出未经检查的异常,而不是,事情可能有所不同)。
幸运的是, 由于4.3,Spring MVC的ExceptionHandlerMethodResolver
(它处理@ExceptionHandler
)可以解开的cause
异常( 见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>
订单场是因为通过上按顺序异常解析器春周期很重要。 您还可以定义这种为自己的异常映射,你是好去!
检查这个博客帖子和Javadoc文档的SimpleMappingExceptionResolver
我们正在使用org.apache.commons.lang.exception.ExceptionUtils ...
private myMethod (Throwable t) {
if (ExceptionUtils.getRootCause(t) instanceof MyException) ...
}