拦截器
SpringMVC的拦截器类似于Servlet开发中的过滤器Filter,也可以形成拦截器链。拦截器interceptor也是AOP思想的具体实现。
拦截器和过滤器区别:
- 拦截器是SpringMVC框架的,只有SpringMVC框架可以使用;在url-pattern中配置了/*之后,可以对所有访问资源拦截。
- 过滤器是Servlet规范的一部分,任何JavaWeb工程都可以使用;只会拦截访问的控制器方法(业务方法),不会拦截jsp/html/css/image等
实现步骤
-
写一个controller,或者多个
@Controller public class UserController { @RequestMapping("/test") public void save() { System.out.println("save running"); } }
-
创建拦截器类实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor { // 在目标方法执行之前 @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return true; } // 在目标方法执行之后,视图对象返回之前 @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); } }
-
配置spring-mvc.xml文件
<!-- 配置拦截器--> <mvc:interceptors> <mvc:interceptor> <!-- 哪些资源执行拦截器:所有资源--> <mvc:mapping path="/**"/> <bean class="com.controller.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
-
测试
preHandle
return 如果是true,表示放行,如果是false,表示拦截。
配置文件
如果有多个拦截器,拦截器链配置如下(按照配置中的顺序执行)
<!-- 配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 哪些资源执行拦截器:所有资源-->
<mvc:mapping path="/**"/>
<bean class="com.controller.MyInterceptor1"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 哪些资源执行拦截器:所有资源-->
<mvc:mapping path="/**"/>
<bean class="com.controller.MyInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
异常
系统中异常包括两类:预期异常和运行时异常。前者通过捕获解决,后者通过测试、规范代码等减少。
系统的DAO/Service/Controller各层出现异常都会向上抛出,最后由SpringMVC前端控制器交给异常处理器统一处理(HandlerExceptionResolver)。
SpringMVC异常处理有两种方式:
- 使用SpringMVC提供的简单异常处理器SimpleMappingExceptionResolver
- 自定义异常类实现HandlerExceptionResolver接口
graph LR
A[客户端]
A---B[SpringMVC前端控制器]
B---C[Controller层]
C---D[Service层]
D---E[DAO层]
简单异常处理器
简单异常处理器不需要定义,但需要在spring-mvc.xml中配置。
<!--异常处理-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="defaultErrorView" value="error.html"/>
<property name="exceptionMappings">
<map>
<!--自定义异常类型-->
<entry key="com.myexception.MyException1" value="error.html"/>
<!--类转换异常类型-->
<entry key="java.lang.ClassCastException" value="error.html"/>
</map>
</property>
</bean>
自定义异常
自定义异常处理器先定义,再配置(配置方法和上面一样)。
如自定义一个异常,需要判断异常类型,最后返回一个视图:
public class MyException implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if (e instanceof ArithmeticException){
modelAndView.addObject("info", "除数为0异常");
} else if (e instanceof ClassCastException) {
modelAndView.addObject("info", "类转换异常");
}
modelAndView.setViewName("error.jsp");
return modelAndView;
}
}