Spring MVC 拦截器是我们项目开发中用到的一个功能,常常用于对Handler进行预处理和后处理。本案例来演示一个较简单的springmvc拦截器的使用。
说明:
Spring MVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
作用:
用户可以自己定义一些拦截器来实现特定的功能。例:访问特定页面前验证用户是否登陆等
拦截器链:
谈到拦截器,还要向大家提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
1、springmvc拦截器使用
1.1 项目初始搭建
创建一个maven的war工程
该步骤不再截图说明
1.1.2 引入maven依赖
<dependencies> <dependency> <groupId>org.springframeworkgroupId> <artifactId>spring-contextartifactId> <version>5.0.2.RELEASEversion> dependency> <dependency> <groupId>org.springframeworkgroupId> <artifactId>spring-webartifactId> <version>5.0.2.RELEASEversion> dependency> <dependency> <groupId>org.springframeworkgroupId> <artifactId>spring-webmvcartifactId> <version>5.0.2.RELEASEversion> dependency> <dependency> <groupId>javax.servletgroupId> <artifactId>servlet-apiartifactId> <version>2.5version> <scope>providedscope> dependency> <dependency> <groupId>javax.servlet.jspgroupId> <artifactId>jsp-apiartifactId> <version>2.0version> <scope>providedscope> dependency>dependencies>
1.2.3 配置web.xml
配置springmvc核心控制器DispatcherServlet,由于需要加载springmvc.xml,所以需要创建一个springmvc.xml文件(文件参考源码附件)放到classpath下
<servlet> <servlet-name>dispatcherServletservlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class> <init-param> <param-name>contextConfigLocationparam-name> <param-value>classpath:springmvc.xmlparam-value> init-param> <load-on-startup>1load-on-startup>servlet><servlet-mapping> <servlet-name>dispatcherServletservlet-name> <url-pattern>/url-pattern>servlet-mapping>
1.2 拦截器开发
1.2.1 准备两个拦截器
两个拦截器分别命名为MyInterceptor1、MyInterceptor2
public class MyInterceptor1 implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("==1-1====前置拦截器1 执行======"); return true; //ture表示放行 } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { System.out.println("==1-2=====后置拦截器1 执行======"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("==1-3======最终拦截器1 执行======"); }}public class MyInterceptor2 implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("==2-1====前置拦截器2 执行======"); return true; //ture表示放行 } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { System.out.println("==2-2=====后置拦截器2 执行======"); } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("==2-3======最终拦截器2 执行======"); }}
1.2.2 在springmvc.xml中拦截器
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.itheima.interceptor.MyInterceptor1" /> mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**" /> <bean class="com.itheima.interceptor.MyInterceptor2" /> mvc:interceptor>mvc:interceptors>
这两个拦截器拦截规则相同,并且配置顺序拦截器1在拦截器2之前!
1.3 测试拦截器效果
1.3.1 准备测试Controller
@Controllerpublic class BizController { @RequestMapping("testBiz") public String showUserInfo(Integer userId, Model model){ System.out.println(">>>>>业务代码执行-查询用户ID为:"+ userId); User user = new User(userId); user.setName("宙斯"); model.addAttribute("userInfo",user); return "user_detail"; }}
该controller会转发到user_detail.jsp页面
1.3.2 准备user_detail.jsp
<html><head> <title>detailtitle>head><body> 用户详情: ${userInfo.id}:${userInfo.name} <%System.out.print(">>>>>jsp页面的输出为:");%> <%System.out.println(((User)request.getAttribute("userInfo")).getName());%>body>html>
1.3.3 测试效果
启动项目后,在地址栏访问/testBiz?userId=1,然后查看IDE控制台打印:
==1-1====前置拦截器1 执行======
==2-1====前置拦截器2 执行======
>>>>>业务代码执行-查询用户ID为:1
==2-2=====后置拦截器2 执行======
==1-2=====后置拦截器1 执行======
>>>>>jsp页面的输出为:宙斯
==2-3======最终拦截器2 执行======
==1-3======最终拦截器1 执行======
通过打印日志发现,拦截器执行顺序是:拦截器1的前置>拦截器2的前置>业务代码>拦截器2后置>拦截器1后置>拦截器2最终>拦截器1最终