SpringMVC拦截器怎么使用
今天小编给大家分享一下SpringMVC拦截器怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
SpringMVC 的拦截器 Interceptor 的主要用来拦截指定的用户请求,并进行相应的预处理或后处理。它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登录等操作。
其拦截的时间点是在处理器适配器执行处理器之前。创建拦截器类需要实现 HandlerInterceptor 接口,然后在配置文件中注册并指定拦截目标。
对于 SpringMVC 拦截器的定义方式有两种:
实现接口: org.springframework.web.servlet.Handlerlnterceptor
继承适配器: org.springframework.web.servethandler.HandlerInterceptorAdapter
项目准备
目录结构:
为了便于下面知识结构的讲解,先创建好未使用拦截器的项目,步骤如下:
【1】创建 spring-config.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 http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--逻辑视图前缀--> <property name="prefix" value="/WEB-INF/jsp/"></property> <!--逻辑视图后缀,匹配模式:前缀+逻辑视图+后缀,形成完整路径名--> <property name="suffix" value=".jsp"></property> </bean> <!-- 配置组件扫描器 --> <context:component-scan base-package="cn.hh.springmvc03"/></beans>
【2】创建 User 实体类,代码如下:
package cn.hh.springmvc03.entity;import lombok.Data;@Datapublic class User {String username;String password;}
单个拦截器的执行流程
项目案例:创建第一个拦截器。
实现步骤:
【1】新建处理器 UserController,添加方法如下:
//测试拦截器@RequestMapping("/test1.do")public String doTestInterceptor(){System.out.println("执行了处理器的方法!");return "welcome";}
【2】新建包 cn.hh.springmvc03.intercepter,在包下新建一个自定义拦截器类 Intercepter1,实现 HandlerInterceptor 接口,重写以下3个方法,代码如下:
package cn.hh.springmvc03.intercepter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;public class Intercepter1 implements HandlerInterceptor{@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception arg3)throws Exception {System.out.println("执行了Intercepter1 ----------afterCompletion");}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception {System.out.println("执行了Intercepter1 ----------postHandle");}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("执行了Intercepter1 ----------preHandle");return true;}}
自定义拦截器,需要实现HandlerInterceptor接口,实现该接口中的以下三个方法:
preHandle(request, response, Object handler): 该方法在处理器方法执行之前执行。其返回值为boolean,若为true,则紧接着会执行处理器方法,且会将afterCompletion()方法放入到一个专门的方法栈中等待执行。若为false则不会执行处理器方法。
ØpostHandle(request, response, Object handler, modelAndView): 该方法在处理器方法执行之后执行。处理器方法若最终未被执行,则该方法不会执行。由于该方法是在处理器方法执行完后执行,且该方法参数中包含ModelAndView,所以该方法可以修改处理器方法的处理结果数据,且可以修改跳转方向。
afterCompletion(request, response, Object handler, Exception ex): 当 preHandle()方法返回 true 时,会将该方法放到专门的方法栈中,等到对请求进行响应的所有工作完成之后才执行该方法。
拦截器中方法与处理器方法的执行顺序如图所示。
也可以这样来看 ,如下图:
【3】在 spring-config.xml 配置文件中注册拦截器,代码如下:
<!-- 注册拦截器 --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="cn.hh.springmvc03.intercepter.Intercepter1"/> </mvc:interceptor> </mvc:interceptors>
【4】运行测试,则控制台输出如下:
执行了Intercepter1 ----------preHandle
执行了处理器的方法!
执行了Intercepter1 ----------postHandle
执行了Intercepter1 ----------afterCompletion
多个拦截器的执行流程
项目案例: 创建多个拦截器。(在上面案例的基础上编写以下代码)
【1】创建Intercepter2,代码如下所示:
package cn.hh.springmvc03.intercepter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;public class Intercepter2 implements HandlerInterceptor{@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception arg3)throws Exception {System.out.println("执行了Intercepter2----------afterCompletion");}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception {System.out.println("执行了Intercepter2----------postHandle");}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("执行了Intercepter2----------preHandle");return true;}}
【2】在 spring-config.xml 文件中注册多个拦截器,代码如下:
<!-- 注册多个拦截器 --><mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.lifeng.intercepter.Intercepter1"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.lifeng.intercepter.Intercepter2"/> </mvc:interceptor> </mvc:interceptors>
【3】运行测试,则控制台输出如下:
执行了Intercepter1 ----------preHandle
执行了Intercepter2 ----------preHandle
执行了处理器的方法!
执行了Intercepter2 ----------postHandle
执行了Intercepter1 ----------postHandle
执行了Intercepter2 ----------afterCompletion
执行了Intercepter1 ----------afterCompletion
当有多个拦截器时,形成拦截器链。拦截器的执行顺序与其注册顺序一致。需要再次强调一点的是当某一个拦截器的 preHandle() 方法返回 true 并被执行到时,会向一个专门的方法栈中放入该拦截器的 afterCompletion() 方法。
多个拦截器方法与处理器方法的执行顺序如下图所示:
只要有一个 preHandler() 方法返回 false,则上部的执行链将被断开,其后续的处理器方法与 postHandle() 方法将无法执行。但无论执行链执行情况怎样,只要方法栈中有方法,即执行链中只要有 preHandle() 方法返回 true,就会执行方法栈中的 afterCompletion() 方法,最终都会给出响应。
权限拦截器(案例分享)
项目案例: 只有经过登录的用户方可访问处理器,否则,将返回“无权访问”提示。 本例的登录,由一个 JSP 页面完成。即在该页面里将用户信息放入 session 中。也就是说,只要访问过该页面,就说明登录了。没访问过,则为未登录用户。
实现步骤:
【1】web.xml 代码如下:
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <!--配置前端控制器--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-config.xml</param-value> </init-param> <!--tomcat启动就创建该实例对象--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping></web-app>
【2】spring-config.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 http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--实现更加强大的功能,支持json数据格式的解析--> <mvc:annotation-driven></mvc:annotation-driven> <!--第5步:配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--前缀配置--> <property name="prefix" value="/"></property> <!--后缀配置--> <property name="suffix" value=".jsp"></property> </bean> <!--第6步:开启包扫描 base-package 设置需要扫描的包 --> <context:component-scan base-package="cn.kgc.springmvc03"></context:component-scan> <!--静态资源的处理 不需要经过前端控制器 tomcat--> <mvc:default-servlet-handler></mvc:default-servlet-handler> <!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/user/login"/> <mvc:exclude-mapping path="/user/getcode"/> <bean class="cn.kgc.springmvc03.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> <!--配置文件上传组件--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean></beans>
【3】UserController 类中添加登陆方法,代码如下:
//登陆 @RequestMapping("login") @ResponseBody public Map<String,Object> login(User user, HttpSession session,@SessionAttribute("code") String attribute){ HashMap<String, Object> map = new HashMap<>(); System.out.println("--------login方法-------"+attribute); if(user.getCode().equals(attribute)){//验证码填写正确 if("tom".equals(user.getUsername())&&"123456".equals(user.getPassword())){//账号密码正确 session.setAttribute("user",user); map.put("code",200); map.put("msg","登陆成功"); }else{//账号密码不正确 map.put("code",500); map.put("msg","登陆失败"); } }else{//验证码填写不正确 map.put("code",500); map.put("msg","验证码输入不正确"); } return map; }
【4】添加拦截器 LoginInterceptor 代码如下:
package cn.kgc.springmvc03.interceptor;import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("-------------preHandle方法--------------"); HttpSession session = request.getSession(); Object user = session.getAttribute("user"); if(user==null){ response.sendRedirect("/login.jsp"); return false; } return true; }}
【5】添加前端页面 login.jsp 代码如下:
<%-- Created by IntelliJ IDEA. Time: 9:35 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>Title</title> <script type="text/javascript" class="lazy" data-src="jquery-1.11.1.js"></script> <script class="lazy" data-src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script></head><body><form> <p><input type="text" name="username" placeholder="请输入用户名" id="username"></p> <p><input type="password" name="password" placeholder="请输入密码" id="password"></p> <p><input type="text" name="code" placeholder="请输入验证码" id="code"></p> <p><input type="button" value="登录" id="login"></p></form><span id="msg" ></span></body><script> $("#login").click(function () { let username=$("#username").val() let password = $("#password").val() let code = $("#code").val() $.get("/user/login",{username,password,code},function (res) { if(res.code=200){ window.location.href="/main.jsp" rel="external nofollow" }else{ let info = res.msg $("#msg").text(info) } }) });</script></html>
以上就是“SpringMVC拦截器怎么使用”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341