Java 在SpringMVC中处理包装异常
我有春季MVC和杰克逊。当我启动一个错误的请求时,Jackson映射失败,并引发Java 在SpringMVC中处理包装异常,java,spring,exception,spring-mvc,exception-handling,Java,Spring,Exception,Spring Mvc,Exception Handling,我有春季MVC和杰克逊。当我启动一个错误的请求时,Jackson映射失败,并引发UnrecognizedPropertyException。我想使用 @ExceptionHandler public String handle(UnrecognizedPropertyException e) { ... } 但是Spring将此异常包装在HttpMessageConversionException中,因此上面的代码不起作用。在Spring中是否可以处理特定于Jackson(或一般特定于库)
UnrecognizedPropertyException
。我想使用
@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
...
}
但是Spring将此异常包装在HttpMessageConversionException
中,因此上面的代码不起作用。在Spring中是否可以处理特定于Jackson(或一般特定于库)的异常?不幸的是,它是IOException
的一个子类型。处理@RequestBody
的RequestResponseBodyMethodProcessor
(我假设这就是异常发生的地方)对IOException
有特殊的处理(解释为请求输入流的失败),将其包装在httpMessageDataableException
中。此外,如果在转换过程中出现转换错误,该接口被指定为抛出httpmessagenoteradableexception
无论发生什么,你都必须处理这个问题(如果Jackson抛出未检查的异常,情况可能会有所不同)
幸运的是,(哪个进程@ExceptionHandler
)可以打开异常的原因()。因此,假设您在httpmessageradableexception
的继承层次结构中没有任何异常的处理程序,那么您的处理程序方法
@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
...
}
将用于处理异常。在Spring MVC查找可以处理HttpMessageTreadableException
的处理程序方法后,会发生这种情况,然后使用展开嵌套异常并再次尝试查找
在4.3之前的版本中,或者如果您在httpmessageradableexception
的继承层次结构中确实有异常类型的处理程序,则您可以在自己提取原因后始终委托
@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>
order字段很重要,因为Spring以该顺序循环通过异常解析程序。您还可以为自己定义这种类型的异常映射,您就可以开始了
查看博客文章和javadoc以了解我们正在使用org.apache.commons.lang.exception.ExceptionUtils
private myMethod (Throwable t) {
if (ExceptionUtils.getRootCause(t) instanceof MyException) ...
}
我想我们有误会。问题是我不能做哦。。知道了。。Spring结束了这个异常。我检查了spring的源代码。除非重写类方法,否则无法执行此操作@索蒂里奥斯的方法似乎best@piotrek你确定这样行吗?我们已经在Spring4.2中尝试过了,但是没有。Spring只记录一条调试消息并丢弃异常(logger.debug(“调用@ExceptionHandler方法失败:+exceptionHandlerMethod,invocationEx)
中的ExceptionHandlerExceptionResolver
)@didirl你说得对。这是很久以前的事了,我不记得我发现了什么。为4.3版本编辑。@SotiriosDelimanolis现在这是一个编辑版本!我在发帖时没想到会这样。由于我们也是4.3之前的版本,您认为我的解决方案如何避免您建议的解决方案所需的所有实例?@didierr甚至更好,除非您可能有多个HandlerExceptionResolver
bean。你可以考虑注入<代码> HooLeRealExpReValueField并让它算出。@ didiel是的,如果你使用<代码> WebMvcConfigurationSupport < /代码>或<代码> <代码>,它会暴露出一个单独的<代码> HuffelExvestRealVelePosie bean(除非你已经声明了你自己),它封装了一些默认实现。