异常映射 1、引言 项目在运行过程中有时会抛异常,对于 Web 应用来说,默认情况下异常信息会显示到页面上。开发的时候倒没什么,可是让用户看到就不好了。
SpringMVC 提供了一套机制将异常类型和一个视图对应起来。
因此我们需要捕获到这个异常,就去我们准备好的页面,让用户看到的是更加友好的错误页面。
……
2、基于 XML 配置异常映射 ① 配置 Spring 配置文件 spring-mvc 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <bean class ="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" id ="exceptionResolver" > <property name ="exceptionMappings" > <props > <prop key ="java.lang.ArithmeticException" > show-message</prop > <prop key ="java.lang.RuntimeException" > show-runtime-message</prop > <prop key ="java.lang.Exception" > show-exception-message</prop > </props > </property > <property name ="exceptionAttribute" value ="testException" /> </bean >
② 测试:编写一个异常对应的 jsp 页面 1 2 3 4 5 6 7 8 9 10 11 12 13 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html > <head > <title > 系统信息</title > </head > <body > <a href ="${pageContext.request.contextPath}/index.jsp" > 回首页</a > </br > 异常对象:${requestScope.testException}<br > 异常消息: ${requestScope.testException.message}<br > </body > </html >
3、基于注解配置异常映射 注意:如果 XML 中也配置了相同的映射关系,那么 SpringMVC 会优先采纳基于注解的映射
① 方法一 创建一个类,使用@ControllerAdvice 标记
然后使用标记了@ExceptionHandler 注解的方法进行异常映射。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @ControllerAdvice public class MyExceptionResolver { @ExceptionHandler(value = Exception.class) public ModelAndView exceptionMapping ( // 方法形参位置接收SpringMVC捕获到的异常对象 Exception exception ) { ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("exceptionClass" , exception); modelAndView.setViewName("show-annotation-message" ); return modelAndView; }
② 方法二 1 2 3 4 5 6 7 8 9 10 11 @ControllerAdvice public class MyExceptionResolver { @ExceptionHandler(value=Exception.class) public void exceptionResolver (Exception exception, HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=UTF-8" ); PrintWriter writer = response.getWriter(); writer.write("使用HttpServletResponse对象返回的响应数据!!!" ); } }
结果:如果有异常,会在对应的请求页面显示【使用 HttpServletResponse 对象返回的响应数据!!!】
注意这里为什么不返回视图了呢?(没有 return ”xxxxx”;)
因为如果浏览器发送的是一个 Ajax 请求,那么返回视图是处理不了的,需要返回 JavaScript 程序能够处理的数据片段。
[1]判断是否为 Ajax 请求依据 1 2 if (accept.contains("application/json" ) || xRequestedWith != null )
[2]同时适配普通请求和 Ajax 请求的异常处理 需要额外导入 jar 包
gson-2.2.4
jackson-all-1.9.11
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 @ExceptionHandler(value = Exception.class) public ModelAndView resolveException ( Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException { String accept = request.getHeader("Accept" ); String xRequestedWith = request.getHeader("X-Requested-With" ); if (accept.contains("application/json" ) || xRequestedWith != null ) { Map<String,String> exceptionInfomationMap = new HashMap<>(); exceptionInfomationMap.put("exceptionClass" , exception.getClass().getName()); exceptionInfomationMap.put("exceptionMessage" , exception.getMessage()); Gson gson = new Gson(); String json = gson.toJson(exceptionInfomationMap); response.setContentType("application/json;charset=UTF-8" ); response.getWriter().write(json); return null ; } ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("exception" , exception); modelAndView.setViewName("show-annotation-message" ); return modelAndView; }