handlerexceptionresolver ajax,SpringMVC-异常处理(二)

通过实现HandlerExceptionResolver接口可以实现对处理的除理,但是还是会留掉一些异常如:RequestParam参数没有传导致的MissingServletRequestParameterException,http的方法有误导致的HttpRequestMethodNotSupportedException等等,这些异常不对被自己定义的HandlerExceptionResolver扑捉。

异常扑捉的关键点:

在DispatcherServlet.initHandlerExceptionResolvers()对异常处理类进行初始化并且排序

private void initHandlerExceptionResolvers(ApplicationContext context) {

this.handlerExceptionResolvers = null;

if (this.detectAllHandlerExceptionResolvers) {

// 从Spring容器中查找HandlerExceptionResolver的实现类

Map matchingBeans = BeanFactoryUtils

.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);

if (!matchingBeans.isEmpty()) {

this.handlerExceptionResolvers = new ArrayList<>(matchingBeans.values());

// 根据HandlerExceptionResolvers实现类的order排序,order越小排在越上面

AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);

}

}

...

}

默认的实现有三个类:ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver,对应的order分别0、1、2 我们自己实现HandlerExceptionResolver类对异常处理,如类名为GlobalExceptionResolver,如果不指定order,默认排序就排在最后,即:ExceptionHandlerExceptionResolver、ResponseStatusExceptionResolver、DefaultHandlerExceptionResolver、GlobalExceptionResolver。所以MissingServletRequestParameterException、HttpRequestMethodNotSupportedException等异常会被DefaultHandlerExceptionResolver扑捉。

重写DefaultHandlerExceptionResolver的异常处理方法

DefaultHandlerExceptionResolver默认实现了一些异常处理如:HttpRequestMethodNotSupportedException、HttpMediaTypeNotSupportedException等,详见:org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver的doResolveException方法,我们可以继承DefaultHandlerExceptionResolver并重写它的方法。

public class SampleDefaultHandlerExceptionResolver extends DefaultHandlerExceptionResolver {

/**

* 重写默认的MissingServletRequestParameterException异常的处理方法

*

* @return

* @throws IOException

*/

@Override

protected ModelAndView handleMissingServletRequestParameter(MissingServletRequestParameterException ex,

HttpServletRequest request,

HttpServletResponse response,

@Nullable Object handler) throws IOException {

if (handler instanceof HandlerMethod) {

return buildJsonResponse(request, response, (HandlerMethod) handler, ex);

}

return super.handleMissingServletRequestParameter(ex, request, response, handler);

}

/**

* 构建JSON数据

*

* @return

*/

private ModelAndView buildJsonResponse(HttpServletRequest request,

HttpServletResponse response,

HandlerMethod handlerMethod,

Exception ex) {

BaseResponse baseResponse = new BaseResponse().setCode("10").setMessage(ex.getMessage());

// 使用jackson,也可以换成fastjson

ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());

modelAndView.addObject("result", baseResponse);

return modelAndView;

}

}

被Spring管理并且设置它的order

也可以让自定义的异常处理类GlobalExceptionResolver继承DefaultHandlerExceptionResolver,重写需要处理的异常,并且设置order属性

public class GlobalExceptionResolver extends DefaultHandlerExceptionResolver implements HandlerExceptionResolver {

@Override

public ModelAndView resolveException(HttpServletRequest request,

HttpServletResponse response,

Object o,

Exception e) {

if (o instanceof HandlerMethod) {

HandlerMethod handlerMethod = (HandlerMethod) o;

log.error("异常#Controller={},Method={}", handlerMethod.getBean(), handlerMethod.getMethod().getName(), e);

// todo 判断属于Ajax的请求还是普通的页面请求

if (isAsyncRequest(request, handlerMethod)) {

// 返回JSON格式数据

return buildJsonResponse(request, response, handlerMethod, e);

} else {

// 返回重定向页面

return buildViewResponse(request, response, handlerMethod, e);

}

}

return null;

}

....

/**

* 重写默认的MissingServletRequestParameterException异常的处理方法

*

* @return

* @throws IOException

*/

@Override

protected ModelAndView handleMissingServletRequestParameter(MissingServletRequestParameterException ex,

HttpServletRequest request,

HttpServletResponse response,

@Nullable Object handler) throws IOException {

return this.resolveException(request, response, handler, ex);

}

}

这样也可以被我们自己的异常处理类扑捉

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值