1.基本介绍60
Interceptor拦截器在SpringMVC中非常重要和有用,其主要功能是拦截指定
用户要求,并进行相应的预处理和后处理。拦截时间点为“处理器映射器根据用户提出”
提交的请求映射了要执行的处理器类,并找到了要执行的处理器类的处理器适配器,
在处理器适配器执行处理器之前”。当然,当处理器映射器映射要执行的处理器类别时,
拦截器和处理器已经组合成处理器执行链,并返回到中央调度器。
1)拦截器是springmvc中的一种,需要实现Handlerinterceptor接口。
2)拦截器与过滤器相似,功能方向侧重点不同。过滤器用于过滤器请求参数,并设置编码字符集。拦截器是拦截用户的请求并判断请求。
3)拦截器是全局的,可以拦截多个controller。一个项目可以有0个或多个拦截器,他们一起拦截用户的请求。
拦截器常用于:用户登录处理、权限检查、日志记录。
2.拦截器的使用步骤:601.定义类实现Handlerinterceptor接口
2.在springmvc配置文件中,声明拦截器,让框架知道拦截器的存在。
3.拦截器的执行时间:601)在要求处理之前,即controller类中的方法在执行之前被拦截。
2)拦截器也将在执行控制器方法后执行。
3)拦截器也将在请求处理完成后执行。
拦截器:作为多个Controller中的公共功能,集中在拦截器的统一处理上。使用aop的思想
4.拦截器执行62自定义拦截器需要实现Handlerinterceptor接口。该接口包含三种方法:
4.1preHandle(request,response,Objecthandler):62preHandle称为预处理方法。
该方法在处理器方法执行前执行。其返回值为boolean。
4.1.1重点:62是整个项目的入口和门户。当preHandle返回true的请求可以处理,则然后执行处理器方法,并将aftercompletion()方法放入专用方法栈中等待执行。preHandle返回false,请求到此方法结束。
4.1.2参数:26Objecthandler:被拦截的控制器对象(即Mycontroller对象)
4.1.boolean623返回值true:请求通过了拦截器的验证,可以执行处理器方法。
执行
Myinterceptor的preHandle()
=====在MyController中执行dosome方法=====
Myinterceptor的postHandle()
Myinterceptoraftercompletion()
false:请求未经拦截器验证,请求到达拦截器后截止,请求未处理。
只执行
Myinterceptor的preHandle()
4.1.4特点:621.控制器方法中的方法(MyController)doSome)以前执行过。用户的请求首先达到这种方法
2.可以在此方法中获取请求信息,验证请求是否符合要求。验证用户是否登录,用户是否有权访问连接地址(url)。
如果验证失败,请求可以截断,请求不能处理。
如果验证成功,可以放行请求,此时可以执行控制器方法。
4.2postHandle(request,response,Objecthandler,modelAndView):62postHandle:后处理方法。
4.2.1重点62该方法在处理器方法执行后执行。如果最终没有执行处理器方法,则不会执行该方法。由于该方法是在处理器方法执行后执行的,该方法的参数包含ModelAndview,因此该方法可以修改处理器方法的处理结果数据和跳转方向。
4.2.2参数:62Objecthandler:Mycontroller被拦截的处理器对象
ModelAndViewmv:处理方法的返回值
4.2.3特点:621.处理器方法后执行(MyController.doSome())
2.ModelAndview可以获得处理器方法的返回值,ModelAndview可以修改
影响最终执行结果的数据和视图。
3.主要对原执行结果进行二次修正
4.3afterCompletion(request,response,Objecthandler,Exceptionex):62afterCompletion:最后执行的方法
4.3.1重点62当prehandle()方法返回true时,将该方法放入一个特殊的方法堆栈中,直到所有响应请求的工作完成。也就是说,该方法是在中央调度器渲染(数据填充)响应页面后执行的,此时对modelandview的再操作也没有帮助。
aftercompletion的最终实施方法,如在controller方法中添加的数据,以清除资源
4.3.2参数62Objecthandler:被拦截器的处理器对象
Exceptionex:异常发生在程序中
4.3.3特点:621.请求处理完成后执行。框架规定,当您的视图处理完成后,视图被执行forward。
认为完成了请求处理。
2.一般做资源回收工作,在程序请求过程中创建一些对象,可以在这里删除,回收占用的内存。
4.4拦截器中方法和处理器方法的执行顺序如下图所示:63另一种表达方式也可以这样理解:
5.步骤615.1新建mavenweb项目61index.jsp
<%--异常处理 57--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><% String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";%><html><head> <title>Title</title> <base href="<%=basePath%>" /></head><body><p>一个拦截器</p><form action="some.do" method="post"> 姓名:<input type="text" name="name"> <br/> 年龄:<input type="text" name="age"> <br/> <input type="submit" value=“提交请求”></form></body></html>
5.2加入依赖
以下省略,不整理
pom.xml
web.xml
5.3创建Controler
package com.bjpowernode.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;/** * 拦截器 61 */@Controllerpublic class MyController { @RequestMapping(value = "/some.do") public ModelAndView doSome(String name,Integer age){ System.out.println(" =====执行Mycontroler中的dosome方法====); ///处理some.do请求了。 相当于service调用处理的完成。 ModelAndView mv = new ModelAndView(); mv.addObject("myname",name); mv.addObject("myage",age); mv.setViewName("show"); return mv; }}
5.4作为拦截器创建一个普通类别
1)实现Handlerinterceptor接口
2)在接口中实现三种方法
MyInterceptor
package com.bjpowernode.handler;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.Date;//创建拦截器,拦截用户请求 61public class MyInterceptor implements HandlerInterceptor { private long btime = 0; /* * preHandle称为预处理方法。 62 * 重要的是:是整个项目的入口和门户。 62 * 重要的是:是整个项目的入口和门户。 当preHandle返回true时 请求可以处理。 * preHandle返回false,请求到此方法结束。 * * 参数: * Object handler : 拦截的控制器对象 * boolean返回值 * true:请求通过了拦截器的验证,可以执行处理器方法。 * Myinterceptor的preHandle() =====在MyController中执行dosome方法===== Myinterceptor的postHandle() Myinterceptoraftercompletion() * * false:请求未通过拦截器验证,要求到达截止日期。 请求尚未处理 * Myinterceptor的preHandle() * * * 特点: * 1.控制器方法中的方法(MyController)doSome)以前执行的。 * 用户的请求首先到达这种方法 * * 2.在这个 请求信息可以在方法中获得, 验证要求是否符合要求。 * 用户的请求首先到达这种方法 * * 2.在这个 请求信息可以在方法中获得, 验证要求是否符合要求。 * 验证用户是否登录, 验证用户是否有权访问连接地址(url)。 * 如果验证失败,请求可以截断,请求不能处理。 * 如果验证成功,可以放行请求,此时可以执行控制器方法。 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //btime = System.currentTimeMillis(); System.out.println()"截取器MyinterceptorpreHandle()"; //计算业务逻辑,根据计算结果,返回true或false ///给浏览器一个返回结果 //request.getRequestDispatcher("/tips.jsp").forward(request,response); return true; } /* postHandle:后处理方法。 62 参数: Object handler:Mycontroller被拦截的处理器对象 ModelAndView mv:处理方法的返回值 特点: 1.处理器方法后执行(MyController.doSome()) 2.能够获取到处理方法的返回值ModelAndView,ModelAndview可以修改 影响最终执行结果的数据和视图。 3.主要对原执行结果进行二次修正 ModelAndView mv = MyController.doSome(); postHandle(request,response,handler,mv); */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv) throws Exception { System.out.println()"截取器Myinterceptorposthandle();// ///需要调整原dosome执行结果。// if( mv != null){// ///////// mv.addObject("mydate",new Date());// ////////// mv.setViewName("other");// } } /* afterCompletion:最后执行的方法 62 参数 Object handler:被拦截器的处理器对象 Exception ex:异常发生在程序中 特点: 1.请求处理完成后执行。框架规定,当您的视图处理完成后,将forward执行到视图中。框架规定,当您的视图处理完成后,将forward执行到视图中。 认为完成了请求处理。 2.一般做资源回收工作, 在程序请求过程中创建了一些对象,可以在这里删除并回收占用的内存。 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println()"截取器Myinterceptoraftercompletion()";// long etime = System.currentTimeMillis();// System.out.println("计算从preHandle到请求处理的时间:"+(etime - btime )); }}
5.5创建show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title></head><body> <h3>/WEB-INF/view/show.jsp从request作用域获取数据</h3><br><%-- 展示数据 --%> <h3>myname数据:${myname}</h3><br> <%--这里使用El表达式-%> <h3>myage数据:${myage}</h3></body></html>
5.6创建springmvc配置文件
1)组件扫描仪扫描@Controller注释
2)声明拦截器,并指定拦截请求uri地址
springmvc.xml
<?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:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--声明组件扫描仪 8--> <context:component-scan base-package="com.bjpowernode.controller" /> <!--声明 视图解析器在springmvc框架中, 帮助开发人员设置视图文件的路径 40--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀:视图文件的路径--> <property name="prefix" value="/WEB-INF/view/" /> <!--后缀:视图文件扩展名称--> <property name="suffix" value=".jsp" /> </bean> <!--声明拦截器: 拦截器可以有0或多个 63--> <mvc:interceptors> <!--声明拦截器: 拦截器可以有0或多个 63--> <mvc:interceptors> <!--声明第一个拦截器--> <mvc:interceptor> <!--请求URI地址指定拦截的请求 path:是uri地址,可以使用通配符 ** ** : 表示任何字符,文件或多级目录和目录中的文件 例如,以下路径将被拦截 http://localhost:8080/myweb/user/listUser.do http://localhost:8080/myweb/student/addStudent.do --> <mvc:mapping path=/**> <!--声明拦截器对象--> <bean class="com.bjpowernode.handler.MyInterceptor" /> </mvc:interceptor> </mvc:interceptors></beans>
5.7测试63preHandler方法返回true633
请求通过了拦截器的验证,可以执行处理器方法。
preHandler方法返回falser请求未经拦截器验证,请求到达拦截器后截止。
6.posthandle修改原dosome执行结果64other.jsp
postHandle
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv) throws Exception { System.out.println()"截取器Myinterceptorposthandle(); ///需要调整原dosome执行结果。 64 if( mv != null){ ///修改数据 mv.addObject("mydate",new Date()); ///修改视图 mv.setViewName("other"); } }
修改成功
7.aftercompletion要求完成64项工作计算请求完成的时间
package com.bjpowernode.handler;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.Date;//创建拦截器,拦截用户请求 61public class MyInterceptor implements HandlerInterceptor { private long btime = 0; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { btime = System.currentTimeMillis();////赋值当前的系统时间 System.out.println()"截取器MyinterceptorpreHandle()"; //计算业务逻辑,根据计算结果,返回true或false ///给浏览器一个返回结果 //request.getRequestDispatcher("/tips.jsp").forward(request,response); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv) throws Exception { System.out.println()"截取器Myinterceptorposthandle(); ///需要调整原dosome执行结果。 64 if( mv != null){ ///修改数据 mv.addObject("mydate",new Date()); ///修改视图 mv.setViewName("other"); } } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println()"截取器Myinterceptoraftercompletion()"; long etime = System.currentTimeMillis(); System.out.println("计算从preHandle到请求处理的时间:"+(etime - btime )); }}