https://www.bilibili.com/video/BV1Sb411s7qa
P39~45
异常处理
如果什么都不做,产生异常时(模拟可以除0),会出现500 Internal Server Error
教务系统就是这样🙃
解决步骤
- 编写自定义异常类(用作提示信息)
- 编写异常处理器
- 配置异常处理器(跳转到提示页面)
自定义异常类
1 2 3 4 5 6 7 8
| public class SysException extends Exception{
private String message;
}
|
控制器
捕获异常,抛自定义异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @RequestMapping("/testException") public String testException() throws SysException{
try { int a = 10/0; } catch (Exception e) { e.printStackTrace(); throw new SysException("查询所有用户出现错误了..."); }
return "success"; }
|
异常处理器
实现HandlerExceptionResolver接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class SysExceptionResolver implements HandlerExceptionResolver{
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { SysException e = null; if(ex instanceof SysException){ e = (SysException)ex; }else{ e = new SysException("系统正在维护...."); } ModelAndView mv = new ModelAndView(); mv.addObject("errorMsg",e.getMessage()); mv.setViewName("error"); return mv; }
}
|
配置异常处理器
在springmvc.xml中
1 2
| <bean id="sysExceptionResolver" class="cn.itcast.exception.SysExceptionResolver"/>
|
错误提示页面
1 2 3 4 5 6 7 8 9 10 11
| <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>Title</title> </head> <body>
${errorMsg}
</body> </html>
|
拦截器
SpringMVC的拦截器用于对处理器进行预处理和后处理,类似Servlet的过滤器 Filter
是AOP的体现
拦截器链
将拦截器按一定的顺序联结成一条链,按顺序调用
与过滤器的区别
过滤器是Servlet规范中的一部分,任何java web工程都可以用;拦截器是Spring MVC框架的
过滤器在url-pattern中配置了”/*”后,可以对所有要访问的资源拦截;拦截器只会拦截访问的控制器方法,不会拦截jsp、html等
使用步骤
- 编写拦截器,实现HandlerInterceptor接口
- 配置拦截器
控制器
1 2 3 4 5 6 7 8 9 10 11
| @Controller @RequestMapping("/user") public class UserController {
@RequestMapping("/testInterceptor") public String testInterceptor(){ System.out.println("testInterceptor执行了..."); return "success"; }
}
|
自定义拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class MyInterceptor1 implements HandlerInterceptor{
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("MyInterceptor1执行了...前"); return true; }
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("MyInterceptor1执行了...后"); }
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("MyInterceptor1执行了...最后"); }
}
|
配置
springmvc.xml中
1 2 3 4 5 6 7 8 9 10 11
| <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/user/*"/>
<bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor1" /> </mvc:interceptor> </mvc:interceptors>
|
要拦截的方法和不要拦截的方法配置一个就可以了
这样配置拦截器后,测试输出为
1 2 3 4 5
| MyInterceptor1执行了...前 testInterceptor执行了 MyInterceptor1执行了...后 success.jsp执行了 MyInterceptor1执行了...最后
|
2个拦截器
拦截器代码和第一个一样
配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/user/*"/> <bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor1" /> </mvc:interceptor>
<mvc:interceptor> <mvc:mapping path="/**"/> <bean class="cn.itcast.controller.cn.itcast.interceptor.MyInterceptor2" /> </mvc:interceptor> </mvc:interceptors>
|
输出
1 2 3 4 5 6 7 8
| MyInterceptor1执行了...前1 MyInterceptor1执行了...前2 testInterceptor执行了 MyInterceptor1执行了...后2 MyInterceptor1执行了...后1 success.jsp执行了 MyInterceptor1执行了...最后2 MyInterceptor1执行了...最后1
|