如何提高网站加载速度慢,青岛建设局官方网站,未来最紧缺的十大专业,湛江网站搜索引擎推广目录: 一、拦截器 #xff1a;1. 拦截器的 “概述”2. 拦截器的 “定义” (创建“拦截器”对象)3. 拦截器的 “配置” (让“拦截器”对象生效)4. 拦截器的 “执行流程”“单个拦截器”的执行流程“多个拦截器”的执行流程 二、应用案例一实现用户登录权限验证 作者简介 #… 目录: 一、拦截器 1. 拦截器的 “概述”2. 拦截器的 “定义” (创建“拦截器”对象)3. 拦截器的 “配置” (让“拦截器”对象生效)4. 拦截器的 “执行流程”“单个拦截器”的执行流程“多个拦截器”的执行流程 二、应用案例一实现用户登录权限验证 作者简介 一只大皮卡丘计算机专业学生正在努力学习、努力敲代码中! 让我们一起继续努力学习 该文章参考学习教材为 《Java EE企业级应用开发教程 (Spring Spring MVC MyBatis)》 黑马程序员 / 编著 文章以课本知识点 代码为主线结合自己看书学习过程中的理解和感悟 最终成就了该文章 文章用于本人学习使用 同时希望能帮助大家。 欢迎大家点赞 收藏⭐ 关注哦 侵权可联系我进行删除如果雷同纯属巧合 在实际项目中拦截器 的 使用是非常普遍 的例如在购物网站中通过 拦截器 可以 拦截未登录的用户 禁止其购买商品或者 使用拦截器 来 验证已登录用户是否有相应 的 操作权限 等。在Struts2框架中拦截器是其重要的组成部分而 Spring MVC 中 也提供了拦截器功能通过配置即可对请求进行拦截处理。 一、拦截器
1. 拦截器的 “概述” SpringMVC 中的 拦截器( Interceptor ) 类似于 Servlet中的过滤器( Filter)它主要用于拦截用户请求并做相应的处理。例如通过拦截器可以进行 权限验证、记录请求信息的日志 、判断用户是否登录 等。 2. 拦截器的 “定义” (创建“拦截器”对象) 要使用 SpringMVC中的拦截器就需要对拦截器类进行定义和配置。通常拦截器类可以通过 两种方式来定义。 一种是通过 实现 HandlerInterceptor接口或 继承 HandlerInterceptor接口的实现类 HandlerInterceptorAdapter 来定义;另一种是通过 实现 WebRequestInterceptor接口或 继承 WebRequestInterceptor接口 的 实现类 来定义。 例子如 实现HandlerInterceptor接口的方式来实现SpringMVC拦截器 : //通过实现HandlerInterceptor接口的方式来实现SPringMVC拦截器
public class CustomerInterceptor implements HandlerInterceptor { //该方法在“控制器方法”之前执行其返回值表示“是否中断后续操作”Overridepublic boolean preHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o) throws Exception {return false;}//该方法在“控制器方法”之后执行且“解析视图”之前执行可通过该方法对“模型和视图”进一步修改Overridepublic void postHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {}//该方法在“整个请求”完成之后执行即“视图渲染结束”之后执行通过该方法可进行“资源清理、记录日志信息等”Overridepublic void afterCompletion(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {}
}从上述代码可以看出自定义的拦截器类实现了HandlerInterceptor接口并实现了 接口中的三个方法 。 关于这 三个方法 的 具体描述 如下 : 方法描述preHandler()方法该方法会在 控制器方法 之前执行其 返回值 表示 是否中断后续操作。当其返回值为 true 时表示 继续向下执行当其返回值为 false 时会 中断后续的所有操作 (包括调用下一个拦截器和控制器类中的方法执行等)。postHandle()方法该方法会在 控制器方法 之后执行且 解析视图 之前执行。可以通过此方法对请求域中的 模型和视图 做出 进一步的修改。afterCompletion()方法该方法在 “整个请求完成” 之后执行即 视图渲染结束 之后执行。可以通过此方法实现一些资源清理、记录日志信息等。 要想让刚创建好的 “拦截器”生效就要在 springmvc-config.xml中进行配置让“拦截器”生效。 3. 拦截器的 “配置” (让“拦截器”对象生效) 要 使自定义的拦截器生效还需要在SpringMVC的配置文件 : springmvc-config.xml 中进行配置。 SpringMVC拦截器“配置元素图” 如下所示 SpringMVC拦截器“在springmvc-config.xml” 中配置代码 如下所示 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/context/spring-context.xsd!-- 配置拦截器 --mvc:interceptors!-- 配置“全局拦截器”,拦截所有请求 --bean classcom.myh.interceptor.CustomerInterceptor/!-- 配置“普通拦截器1”,拦截“指定路径”/“指定请求” --mvc:interceptor!-- 需要拦截的路径 --mvc:mapping path/**/bean classcom.myh.interceptor.CustomerInterceptor1//mvc:interceptor!-- 配置“普通拦截器2” --mvc:interceptor!-- 需要拦截的路径 --!-- 拦截所有以 /hello 结尾的路径 --mvc:mapping path/hello/bean classcom.myh.interceptor.CustomerInterceptor2//mvc:interceptor...../mvc:interceptors
/beans在 上述配置代码中mvc:interceptors元素用于配置一组拦截器其子元素bean中定义的 是全局拦截器它会拦截所有的请求而 mvc:interceptor元素 中定义的是指定路径的拦截器 它会对指定路径下的请求生效。mvc:interceptor 元素的子元素mvc:mapping用于配置拦截 器作用的路径该路径在其属性path中定义。如上述代码中path的属性值“/”** 表示拦截所有路径“hello表示拦截所有以hello 结尾的路径。如果在请求路径中包含不需要拦截的内容还可以通过 mvc:exclude- mapping元素进行配置。 注意点 需要注意的是mvc:interceptor中的子元素必须按照上述代码的配置顺序进行编写即 mvc:mapping — mvc:exclude-mapping — bean 的顺序否则文件会报错。 4. 拦截器的 “执行流程”
“单个拦截器”的执行流程 在 运行程序 时拦截器的执行 是 有一定顺序 的该 顺序 与配置文件中所定义的 拦截器的顺序 相关。如果在项目中只定义了一个拦截器那么该拦截器在程序中的 执行流程如图 如下图所示 从 上图 可以看出程序首先 会 执行拦截器类 中的 preHandle( )方法如果该方法的 返回值为 true 则程序会 继续向下执行 处理器类中的方法 否则不会向下执行 后执行 控制器类中方法 执行完“控制器类中方法”后会执行“拦截器类”中的 postHandle( )方法然后会通过DispatcherServlet 向 各户端返回响应在DispatcherServlet处理完请求后才会执行 afterCompletion( )方法。 “单个拦截器”的执行流程 例子如 第一步、创建项目导入依赖 Spring MVC所需JAR (百度网盘) 第二步 配置 SpringMVC拦截器 的 相关文件 : web.xml : ?xml version1.0 encodingUTF-8?
web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsdversion4.0!-- 配置前端过滤器--servletservlet-namedispatcherServlet/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!-- 配置springmvc-config.xml配置文件的位置 上下文配置位置 --init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:springmvc-config.xml/param-value/init-param!-- 配置启动服务器时加载此配置文件加载此servlet --load-on-startup1/load-on-startup/servlet!-- 配置Servlet的Mapper映射 --servlet-mappingservlet-namedispatcherServlet/servlet-nameurl-pattern//url-pattern/servlet-mapping/web-appspringmvc-config.xml : ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:contexthttp://www.springframework.org/schema/contextxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd!-- 配置组件扫描进行根包扫描让注解生效 --context:component-scan base-packagecom.myh.controller/!-- 配置视图解析器 --bean classorg.springframework.web.servlet.view.InternalResourceViewResolver!-- 前缀 --property nameprefix value/WEB-INF/jsp//!-- 后缀 --property namesuffix value.jsp//bean!-- 配置SpringMVC 拦截器 --mvc:interceptors!-- 全局拦截器会拦截所有请求 --bean classcom.myh.interceptor.CustomerInterceptor//mvc:interceptors/beansHelloController.java (控制器类) : package com.myh.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;Controller //标记该类为控制器类
public class HelloController {/*** 页面跳转*/RequestMapping(/hello)public String Hello() {System.out.println(HelloController...Hello());return success; //响应一个页面给前端}
}CustomerInterceptor.java (拦截器对象) : package com.myh.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class CustomerInterceptor implements HandlerInterceptor { //通过实现HandlerInterceptor接口的方式来实现SPringMVC拦截器//该方法在“控制器方法”之前执行其返回值表示“是否中断后续操作”Overridepublic boolean preHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object handler) throws Exception {//对拦截的请求放行return true;}//该方法在“控制器方法”之后执行且“解析视图”之前执行可通过该方法对“模型和视图”进一步修改Overridepublic void postHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object handler, ModelAndView modelAndView) throws Exception {System.out.println(CustomerInterceptor...postHandle());}//该方法在“整个请求”完成之后执行即“视图渲染结束”之后执行通过该方法可进行“资源清理、记录日志信息等”Overridepublic void afterCompletion(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object handler, Exception e) throws Exception {System.out.println(CustomerInterceptor...afterCompletion());}
}success.jsp : % page contentTypetext/html;charsetUTF-8 languagejava %
html
headtitlesuccess.jsp页面/title
/head
body
ok
/body
/html启动服务器前端访问 /hello 控制台打印内容为 从上图可以看出程序先执行了拦截器类中的 preHandle( )方法然后执行了控制器中的 Hello( )方法最后分别执行了拦截器类中的 postHandle( )方法和afterCompletion( )方法。这 与上文所描述的单个拦截器的执行顺序是一致的。 “多个拦截器”的执行流程 在 大型的企业级项目 中通常 不会只有一个拦截器开发人员可能会定义 多个拦截器 来实现不同的功能。 多个拦截器的执行顺序 如下图 从上图可以看出当有 多个拦截器同时工作 时它们的 preHandle( )方法 会按照配置文件中 拦截器 的 配置顺序执行而它们的 postHandle( )方法 和 afterCompletion( )方法 则会按照 配置顺序 的 “反序执行”。 “多个拦截器”的执行流程 例子如 : 第一步、创建项目导入依赖 Spring MVC所需JAR (百度网盘) 第二步 配置 SpringMVC拦截器 的 相关文件 : web.xml : ?xml version1.0 encodingUTF-8?
web-app xmlnshttp://xmlns.jcp.org/xml/ns/javaeexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsdversion4.0!-- 配置前端过滤器--servletservlet-namedispatcherServlet/servlet-nameservlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class!-- 配置springmvc-config.xml配置文件的位置 上下文配置位置 --init-paramparam-namecontextConfigLocation/param-nameparam-valueclasspath:springmvc-config.xml/param-value/init-param!-- 配置启动服务器时加载此配置文件加载此servlet --load-on-startup1/load-on-startup/servlet!-- 配置Servlet的Mapper映射 --servlet-mappingservlet-namedispatcherServlet/servlet-nameurl-pattern//url-pattern/servlet-mapping/web-appspringmvc-config.xml : ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:mvchttp://www.springframework.org/schema/mvcxmlns:contexthttp://www.springframework.org/schema/contextxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd!-- 配置组件扫描进行根包扫描让注解生效 --context:component-scan base-packagecom.myh.controller/!-- 配置视图解析器 --bean classorg.springframework.web.servlet.view.InternalResourceViewResolver!-- 前缀 --property nameprefix value/WEB-INF/jsp//!-- 后缀 --property namesuffix value.jsp//bean!-- 定义两个拦截器 --mvc:interceptors!-- 拦截器1 --mvc:interceptormvc:mapping path/**/bean classcom.myh.interceptor.Interceptor1//mvc:interceptor!-- 拦截器2 --mvc:interceptormvc:mapping path/hello/bean classcom.myh.interceptor.Interceptor2//mvc:interceptor/mvc:interceptors/beans在上述拦截器的配置代码中第一个拦截器会作用于所有路径下的请求而 第二个拦截器 会作用于以 “hello 结尾的请求。 HelloController.java (控制器类) : package com.myh.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;Controller //标记该类为控制器类
public class HelloController {/*** 页面跳转*/RequestMapping(/hello)public String Hello() {System.out.println(HelloController...Hello());return success; //响应一个页面给前端}
}Interceptor1.java (拦截器对象1) : package com.myh.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/*** 如果有多个拦截器preHandle()方法按照拦截器的“顺序执行”* postHandle()方法 和 afterCompletion()方法按照拦截器的“逆序执行”*/
public class Interceptor1 implements HandlerInterceptor {//以实现HandlerInterceptor接口的方式定义拦截器Overridepublic boolean preHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o) throws Exception {System.out.println(Interceptor1...preHandle());return true; //对拦截的请求放行}Overridepublic void postHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {System.out.println(Interceptor1...postHandle());}Overridepublic void afterCompletion(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println(Interceptor1...afterCompletion());}
}Interceptor2.java (拦截器对象2) : package com.myh.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;/*** 如果有多个拦截器preHandle()方法按照拦截器的“顺序执行”* postHandle()方法 和 afterCompletion()方法按照拦截器的“逆序执行”*/
public class Interceptor2 implements HandlerInterceptor {//以实现HandlerInterceptor接口的方式定义拦截器Overridepublic boolean preHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o) throws Exception {System.out.println(Interceptor2...preHandle());return true; //对拦截的请求放行}Overridepublic void postHandle(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {System.out.println(Interceptor2...postHandle());}Overridepublic void afterCompletion(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {System.out.println(Interceptor2...afterCompletion());}
}success.jsp : % page contentTypetext/html;charsetUTF-8 languagejava %
html
headtitlesuccess.jsp页面/title
/head
body
ok
/body
/html启动服务器前端访问 /hello 控制台打印内容为 从控制体输出信息可以看出程序 先执行 了 前两个拦截器类 中的 preHandle( )方法这 两个方法的执行顺序 与 配置文件中定义 的 顺序相同然后执行了控制器类中的 Hello( )方法; 最后执行了两个拦截器类中的 postHandle( )方法 和 afterCompletion( )方法 且这两个方法的 执行顺序 与配置文件中所 定义 的拦截器 顺序相反。 二、应用案例一实现用户登录权限验证 下面将通过 拦截器 来完成一个 用户登录权限验证 的 案例。本案例中只有登录后的用户才能访问系统中的主页面如果 没有登录系统而直接访问主页面则 拦截器会将请求拦截并转发到登录页面同时在登录页面中给出提示信息。如果 用户名或密码错误也会在登录页面给出 相应的提示信息。当 已登录的用户 在系统主页中单击 “退出” 链接时系统同样会 回到登录页面。 该案例的 整个执行流程 如下图所示 : ( 用户权限验证的执行流程图 ) 该 案例的具体代码 第一步、创建项目导入依赖 Spring MVC所需JAR (百度网盘) 第二步 应用案例一实现用户登录权限验证的 相关代码文件 : User.java package com.myh.po;
public class User {
private Integer id;private String username;private String password;public Integer getId() {return id;}public void setId(Integer id) {this.id id;}public String getUsername() {return username;}public void setUsername(String username) {this.username username;}public String getPassword() {return password;}public void setPassword(String password) {this.password password;}
}UserController.java : 控制器类 package com.myh.controller;import com.myh.po.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;import javax.servlet.http.HttpSession;Controller
public class UserController {/*** 向用户登录页面跳转*/RequestMapping(value /toLogin,method RequestMethod.GET)public String toLogin() {return login;}/*** 用户登录*/RequestMapping(value /login,method RequestMethod.POST)public String login(User user, Model model, HttpSession session) { //Model用于传递属性值//获取用户名和密码String username user.getUsername();String password user.getPassword();//此处模拟从数据库中获取用户名和密码后进行判断if (username ! null username.equals(tom) password ! null password.equals(123)) {//将对象添加到Session中session.setAttribute(USER_SESSION,user); //存session// redirect:/main : 表示用户应被“重定向”到 /main的URL(或视图),此处为重定向到/main这个URLreturn redirect:main; //重定向到“主页面”的跳转方法}model.addAttribute(msg, 用户名或密码错误请重新登录);return login; //因为没登录成功所以重新回到login.jsp页面}/*** 向主页面跳转*/RequestMapping(value /main)public String toMain() {return main;}/*** 退出登陆*/RequestMapping(value /logout)public String logout(HttpSession session) {//清除sessionsession.invalidate();//重定向到“登录页面”的“跳转方法”return redirect:/toLogin;}
}LoginInterceptor.java : 拦截器类 package com.myh.interceptor;
import com.myh.po.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;/*** 登录拦截器*/
public class LoginInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//获取请求的URLString url request.getRequestURI();//url:除了login.jsp可以公开访问的其他的url都要进行拦截控制if ((url.indexOf(/toLogin) 0) |(url.indexOf(/login) 0) ) { //整体意思: 判断url中是否包含/login(包含则证明是关于“登录的请求”给予放行)return true; //只有/login请求才能被放行其他都要进行拦截 (如果是/login则返回值true下面的代码就不用执行了)}/*** 没有被前面的if语句拦截说明url请求不是/login,就判断是否已经登录过了(判断session中是否有登录对象数据)*///获取SessionHttpSession session request.getSession();User user (User)session.getAttribute(USER_SESSION);//判断Session中是否有用户数据如果有返回true继续向下执行if (user ! null) {return true;}//没被上面的if语句拦截说明没有进行登录Session中查不到登录信息最后转发到登录页面request.setAttribute(msg,您还没有登录请先登录);/*调用getRequestDispatcher对象的 .forward(request,response)来进行请求转发将当前的请求对象和响应对象转发到指定的资源 : /WEB-INF/jsp/login.jsp*/request.getRequestDispatcher(/WEB-INF/jsp/login.jsp).forward(request,response);return false; //拦截请求}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) throws Exception {}
}在文件的 preHandle( )方法中先获取了请求的URL然后通过indexOf( )方法判断URL中是否 有 “/login” 字符串 或 “/toLogin” 字符串 。如果有则返回true即 直接放行如果没有则继续向下进 行拦截处理。接下来获取了Session中的用户信息如果Session中包含用户信息即表示用户已登录也直接放行否则会转发到登录页面不再执行后续程序。 main.jsp % page contentTypetext/html;charsetUTF-8 languagejava %
html
headtitle系统主页/title
/head
body
%-- 用{ }获得存在session中的数据 --%当前用户: ${USER_SESSION.username}
a href${pageContext.request.contextPath}/logout退出/a
/body
/htmllogin.jsp : % page contentTypetext/html;charsetUTF-8 languagejava %
html
headtitle用户登录/title
/head
body
span stylecolor: red ${msg}/spanform action${pageContext.request.contextPath}/login methodpost用户名:input typetext nameusername/br密nbsp;nbsp;码:input typepassword namepassword//brinput typesubmit value登录/form
/body
/html将项目发布 Tomcat服务器并启动在浏览器中访问地址”http://localhost:8080/main“其显示效果如下图所示 从上图可以看出当 用户未登录 而 直接访问主页面时访问请求会被登录拦截器拦截从而跳转到登录页面并提示用户未登录信息。如果在用户名输入框中输入jack’ 密码框中输入“123456当单击 “登录”按钮后浏览器的显示结果如下图所示 : 当 输入正确的用户名 tom 和 密码 “123456”并单击“登录”按钮后浏览器会跳转到系统主页面 如下图所示 单击“退出”链接后用户即可退出当前系统系统会从主页面重定向到登录页面。