处理Spring MVC中包裹着的例外(handling wrapped exceptions in

2019-07-22 03:26发布

我有Spring MVC和杰克逊。 当我开始不正确的请求,杰克逊映射失败, UnrecognizedPropertyException被抛出。 我想用处理此异常

@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
  ...
}

然而在春包装这个异常HttpMessageConversionException所以上面的代码不起作用。 是否有可能在春季来处理杰克逊具体的(或一般图书馆专用)异常?

Answer 1:

不幸的是, 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) {
    ...
}


Answer 2:

我做这种方式:

/**
 * 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



Answer 3:

我们正在使用org.apache.commons.lang.exception.ExceptionUtils ...

private myMethod (Throwable t) {

    if (ExceptionUtils.getRootCause(t) instanceof MyException) ...
}


文章来源: handling wrapped exceptions in spring mvc