处理spring mvc中的包装exception
我有Spring MVC和jackson。 当我开始一个不正确的请求时,Jackson映射失败并抛出UnrecognizedPropertyException
。 我想使用处理此exception
@ExceptionHandler public String handle(UnrecognizedPropertyException e) { ... }
但是Spring在HttpMessageConversionException
包装了这个exception,所以上面的代码不起作用。 是否有可能在Spring中处理jackson特定的(或一般的库特定的)exception?
不幸的是, UnrecognizedPropertyException
是IOException
的子类型。 处理@RequestBody
的RequestResponseBodyMethodProcessor
(我假设发生exception的地方)具有对IOException
特殊处理(解释为请求输入流的失败),将其包装在HttpMessageNotReadableException
。 此外,如果在read
期间发生转换错误,则指定HttpMessageConverter
接口抛出HttpMessageNotReadableException
。
无论如何,你将不得不处理这个问题(如果jackson提出了未经检查的例外情况,那么事情可能会有所不同)。
幸运的是, 自4.3以来,Spring MVC的ExceptionHandlerMethodResolver
(处理@ExceptionHandler
)可以解开exception的cause
( 参见SPR-14291 )。 因此,假设您没有HttpMessageNotReadableException
的inheritance层次结构中的任何exception处理程序,那么您的处理程序方法
@ExceptionHandler public String handle(UnrecognizedPropertyException e) { ... }
将用于处理exception。 这发生在Spring MVC查找可处理HttpMessageNotReadableException
的处理程序方法HttpMessageNotReadableException
,然后使用Throwable#getCause
解包嵌套exception并再次尝试查找。
在4.3之前的版本中,或者如果你在HttpMessageNotReadableException
的inheritance层次结构中有一个exception类型的处理程序,你总是可以在自己提取原因后委托。
@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上下文中:
订单字段很重要,因为Spring按顺序循环遍历exception解析器。 你也可以为自己定义这种exception映射,你很高兴!
查看此博客文章和javadoc for SimpleMappingExceptionResolver
- KSOP2图书馆课没有发现exception
- 使用FileUtils.copyFile复制文件
- org.openqa.selenium.UnhandledAlertException:意外警报打开
- 为什么运行时exception是未经检查的exception?
- 为什么不捕获Exception catch RuntimeException?
- exception处理模式
- PrintWriter和PrintStream永远不会抛出IOExceptions
- com.microsoft.sqlserver.jdbc.SQLServerException:索引2超出范围:(
- 扫描仪NoSuchElementException