当controller层出现异常时,对于普通的请求异常我们在web.xml里配置一个统一的跳转页面来提示用户,如下:
<error-page> <error-code>500</error-code> <location>/500.html</location> </error-page>
而对于ajax请求抛出的异常呢,让ajax请求自己捕获显然是不友好的,虽然用户察觉不出什么,但是通过浏览器查看请求返回时,出现服务器返回500错误显然是不友好。所以这里统一处理一下ajax请求,友好的提示用户错误信息。
在Spring MVC中,所有用于处理在请求映射和请求处理过程中抛出的异常的类,都要实现HandlerExceptionResolver接口。HandlerExceptionResolver接口有一个方法resolveException,当controller层出现异常之后就会进入到resolveException这个方法中。
下面我们直接实现HandlerExceptionResolver接口,重写resolveException方法,代码如下:
public class ExceptionResolver implements HandlerExceptionResolver { private static Logger logger = LogManager.getLogger(ExceptionResolver.class); @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { LogUtil.error("", request.getRequestURL().toString(), exception, PlatformNameEnum.DMS, request.getParameterMap(), ""); // 判断是否ajax请求 if ((request.getHeader("accept").indexOf("application/json") > -1 || (request .getHeader("X-Requested-With") != null && request.getHeader( "X-Requested-With").indexOf("XMLHttpRequest") > -1))) { // 如果是ajax请求,JSON格式返回 try { ResultVo resultVo = new ResultVo(false); response.setContentType("application/json;charset=UTF-8"); PrintWriter writer = response.getWriter(); // 为安全起见,只有业务异常我们对前端可见,否则统一归为系统异常 if (exception instanceof BusinessException) { resultVo.setResultAndCode(false, ((BusinessException) exception).getErrorCode(), ((BusinessException) exception).getErrorMessage()); } else { resultVo.setResultAndCode(false, DmsErrorCode.DMS_ERR_100000.getCode(), "系统异常,请联系管理员"); } writer.write(JSON.toJSONString(resultVo)); writer.flush(); writer.close(); } catch (IOException e) { LogUtil.error("", request.getRequestURL().toString(), exception, PlatformNameEnum.DMS, request.getParameterMap(), ""); e.printStackTrace(); } } //对于非ajax请求,我们都统一跳转到500.html页面 return null; } }
另外,我们需要在springmvc配置文件添加如下配置:
<!-- 框架异常处理Handler --> <bean id="exceptionResolver" class="com.zcz.exceptionresolver.MyExceptionResolver"></bean>
到此整个异常处理就结束了。