1.1 拦截器(HandlerInterceptor)
拦截器,顾名思义,用于拦截请求。其可以完成两件工作:
l 处理器执行之前的预处理操作
l 处理器执行之后的后处理操作
其作用类似于过滤器。不同的是,过滤器是Servlet API,即是任何Web程序都可以使用的API。但拦截器是SpringMVC的API,必须在使用SpringMVC框架时才能使用该API。
应用:权限控制器
A、 步骤1:创建任意一个类实现HandlerInterceptor接口,重写其中的三个方法。
preHandle:执行在处理器方法之前
postHandle:执行在处理器方法之后
afterCompletion:当结束之后执行
B、 步骤2:在Spring-mvc.xml 中注册拦截器
(1)添加mvc 的约束头
|
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> |
(2)注册拦截器
|
<!-- 注册拦截器 --> <mvc:interceptors> <mvc:interceptor> <!-- /** 无论下面有一级路径还是二级路径都会被拦截 --> <mvc:mappingpath="/**"/> <beanclass="com.abc.interceptors.OneInterceptor"/> </mvc:interceptor> <mvc:interceptor> <mvc:mappingpath="/**"/> <beanclass="com.abc.interceptors.TwoInterceptor"/> </mvc:interceptor> </mvc:interceptors> |
拦截器的注册顺序,就是拦截的顺序。
C、 步骤3:创建一个处理器方法
执行结果:
1.1.2 拦截器执行原理示意图
针对可能出现的情况:
一个拦截器:
浏览器发送请求,被拦截器(oneInterceptor)拦截,执行preHandler()方法,该方法存在返回值,当return true ,会执行处理器类的处理器方法;当returnfalse ,不会执行到处理器的处理器方法中。一旦执行到处理器方法,则会执行拦截器的postHandler() 方法,再执行afterCompletion()方法,然后返回给浏览器。其中在执行afterCompletion()方法之前,会执行到一个render() 方法,这个方法是渲染方法,既在这个方法中完成对数据的封装。
多个拦截器:
第一种情况:oneInterceptor的preHandler返回false;
浏览器发送请求,被拦截器(oneInterceptor)拦截,执行preHandler()方法,该方法存在返回值,当return false ,只会执行preHandler()中的方法。其它任何方法不执行。
第二种情况:oneInterceptor的preHandler返回true;twoInterceptor的preHandler返回false;
浏览器发送请求,被拦截器(oneInterceptor)拦截,执行preHandler()方法,该方法存在返回值,当return true ,什么也不执行,会执行下一个拦截器(twoInterceptor)的preHandler()方法;当(twoInterceptor)的preHandler()return false;则会导致后面的所有都不执行,但是拦截器(oneInterceptor)的afterCompletion()方法会执行。
1.1.3 源码分析
1.1.4 拦截器的应用-权限控制
功能:判断当前用户是否登陆,不登陆不能进入。
创建一个拦截器
|
package com.abc.interceptors;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView;
public class PermissionInterceptor implements HandlerInterceptor {
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // session对象的获取方式总结: // 1)若要向session中存放数据,一般情况下使用session.getSession(),其等价于session.getSession(true),表示的意义为: // 当前请求若存在Session对象,则使用当前存在的Session;当前若不存在Session对象,则新建一个Session对象。 // 2)若要从session中获取数据,一般情况下使用session.getSession(false),表示的意义为: // 当前请求若存在Session对象,则从当前存在的Session中获取指定属性的值;当前若不存在Session对象,则要获取的指定数据肯定是没有的, // 所以,无需创建Session对象 HttpSession session = request.getSession(false); if (session != null) { String user = (String) session.getAttribute("user"); if("aynu".equals(user)) { return true; } } // 在请求转发与重定向均可使用的前提下,建议使用重定向。为了防止恶意刷新。 response.sendRedirect(request.getContextPath() + "/message.jsp"); return false; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { }
} |
在spring-mvc.xml 注册
|
<!-- 注册拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.abc.interceptors.PermissionInterceptor"/> </mvc:interceptor> </mvc:interceptors> |