【SpringMVC】SpringMVC 拦截器
SpringMVC 拦截器
拦截器的作用
SpringMVC 的处理器拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理。
谈到拦截器,还有另外一个概念 —— 拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定的顺序联结成一条链,在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
处理器拦截器和过滤器的异同:
- 过滤器是 Servlet 规范中的一部分,任何 JavaWeb 工程都可以使用。而拦截器是 SpringMVC 框架独有的,只有使用了 SpringMVC 框架的工程才能使用。
- 过滤器在
url-pattern中配置了/*之后,可以对所有要访问的资源拦截。而拦截器它是只会拦截访问的控制器方法,如果访问的是静态资源则不会进行拦截。
自定义拦截器,要求必须实现 HandlerInterceptor 接口。
自定义拦截器
第一步 编写一个普通类实现 HandlerInterceptor 接口:
/**
* @Author : parzulpan
* @Time : 2020-12
* @Desc : 自定义拦截器
*/
public class CustomInterceptor1 implements HandlerInterceptor {
/**
* 预处理,Controller 方法执行前
* 可以使用转发或者重定向直接跳转到指定的页面
* @param request
* @param response
* @param handler
* @return true 代表放行,执行下一个拦截器,如果没有则执行 Controller 中的方法;false 代表不放行
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("called CustomInterceptor1 preHandle...");
// request.getRequestDispatcher("/WEB_INF/views/error.jsp").forward(request, response);
return true;
}
/**
* 后处理,Controller 方法执行后,success.jsp 执行前
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("called CustomInterceptor1 postHandle...");
// request.getRequestDispatcher("/WEB_INF/views/error.jsp").forward(request, response);
}
/**
* success.jsp 执行后
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("called CustomInterceptor1 afterCompletion...");
}
}
第二步 配置拦截器:
<!-- 配置 处理器拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/> <!-- 要拦截的方法 -->
<!-- <mvc:exclude-mapping path="/**"/> 不要拦截的方法 -->
<bean id="customInterceptor1" class="cn.parzulpan.interceptor.CustomInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
第三步 测试结果:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>拦截器的使用</title>
</head>
<body>
<a href="user/testInterceptor">拦截器的使用</a>
</body>
</html>
输出:
called CustomInterceptor1 preHandle...
called testInterceptor...
called CustomInterceptor1 postHandle...
called success.jsp ...
called CustomInterceptor1 afterCompletion...
拦截器的细节
- preHandle 方法:
- 按拦截器定义顺序调用
- 只要配置了就会调用
- 如果决定该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回 true。如果决定不需要再调用其他的组件去处理请求,则返回 false。
- postHandle 方法:
- 按拦截器定义逆序调用
- 在拦截器链内所有拦截器返回 true 就会调用
- 在业务处理器处理完请求后,但是 DispatcherServlet 向客户端返回响应前被调用,可以在该方法中对用户请求 request 进行处理
- afterCompletion 方法:
- 按拦截器定义逆序调用
- 只有 preHandle 返回 true 才调用
- 在 DispatcherServlet 完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作
多个拦截器的执行顺序:
假设多个拦截器配置为:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="customInterceptor1" class="cn.parzulpan.interceptor.CustomInterceptor1"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean id="customInterceptor2" class="cn.parzulpan.interceptor.CustomInterceptor2"/>
</mvc:interceptor>
</mvc:interceptors>
则 执行顺序为:

拦截器的简单使用
需求:
验证用户是否登录
实现:
- 1、有一个登录页面,需要写一个 controller 访问页面
- 2、登录页面有一提交表单的动作,需要在 controller 中处理。
- 2.1、判断用户名密码是否正确
- 2.2、如果正确 向 session 中写入用户信息
- 2.3、返回登录成功。
- 3、拦截用户请求,判断用户是否登录
- 3.1、如果用户已经登录。放行
- 3.2、如果用户未登录,跳转到登录页面
用户登录控制器 LoginController.java
/**
* @Author : parzulpan
* @Time : 2020-12
* @Desc : 用户登录控制器
*/
@Controller
public class LoginController {
/**
* 登录页面
* @param model
* @return
* @throws Exception
*/
@RequestMapping("/login")
public String login(Model model) throws Exception {
System.out.println("called login...");
return "login";
}
/**
* 提交登录
* @param session
* @param username
* @param password
* @return
* @throws Exception
*/
@RequestMapping("/loginSubmit")
public String loginSubmit(HttpSession session, String username, String password) throws Exception {
System.out.println("called loginSubmit...");
System.out.println(username + " " + password);
session.setAttribute("activeUser", username); // 向 session 记录用户身份信息
return "forward:/WEB-INF/views/main.jsp";
}
/**
* 退出登录
* @param session
* @return
* @throws Exception
*/
@RequestMapping("logout")
public String logout(HttpSession session) throws Exception {
System.out.println("called logout...");
session.invalidate(); // 设置 session 过期
return "redirect:/index.jsp";
}
/**
* 测试页面
* @return
* @throws Exception
*/
@RequestMapping("/test")
public String test() throws Exception {
System.out.println("called test...");
return "test";
}
用户登录拦截器 LoginInterceptor.java
/**
* @Author : parzulpan
* @Time : 2020-12
* @Desc : 用户登录拦截器
*/
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("called LoginInterceptor preHandle...");
//如果是登录页面则放行
if (request.getRequestURI().contains("login")) {
System.out.println("登录页面");
return true;
}
// 如果用户已登录则放行
HttpSession session = request.getSession();
if (session.getAttribute("activeUser") != null) {
System.out.println("用户已登录");
return true;
}
// 用户没有登录跳转到登录页面
System.out.println("用户没有登录");
request.getRequestDispatcher("/WEB-INF/views/login.jsp").forward(request, response);
return false;
}
}
views 页面
src/main/webapp/WEB-INF/views/login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
欢迎登录~
<br>
<form action="loginSubmit" method="post">
用户名:<input type="text" name="username"/><br>
密码:<input type="password" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
src/main/webapp/WEB-INF/views/main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
恭喜您,登录成功~
<br>
<a href="logout">退出登录</a>
<a href="test">进入测试页面</a>
</body>
</html>
src/main/webapp/WEB-INF/views/test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
我已登录,可以进入测试页面~
<br>
<a href="logout">退出登录</a>
</body>
</html>
测试页面
src/main/webapp/index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>拦截器的使用</title>
</head>
<body>
<a href="login">用户登录</a>
<a href="test">测试页面</a>
</body>
</html>
练习和总结
【SpringMVC】SpringMVC 拦截器的更多相关文章
- springmvc的拦截器
什么是拦截器 java里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使 ...
- SpringMVC利用拦截器防止SQL注入
引言 随着互联网的发展,人们在享受互联网带来的便捷的服务的时候,也面临着个人的隐私泄漏的问题.小到一个拥有用户系统的小型论坛,大到各个大型的银行机构,互联网安全问题都显得格外重要.而这些网站的背后,则 ...
- SpringMVC经典系列-14自己定义SpringMVC的拦截器---【LinusZhu】
注意:此文章是个人原创.希望有转载须要的朋友们标明文章出处.假设各位朋友们认为写的还好,就给个赞哈.你的鼓舞是我创作的最大动力,LinusZhu在此表示十分感谢,当然文章中如有纰漏,请联系linusz ...
- 基于注解风格的Spring-MVC的拦截器
基于注解风格的Spring-MVC的拦截器 Spring-MVC如何使用拦截器,官方文档只给出了非注解风格的例子.那么基于注解风格如何使用拦截器呢? 基于注解基本上有2个可使用的定义类,分别是Defa ...
- SpringMVC 学习-拦截器 HandlerInterceptor 类
一.拦截器 HandlerInterceptor 类的作用 SpringMVC 的拦截器类似于 Servlet 开发中的过滤器 Filter,用于对处理器进行预处理和后处理. 二.怎么使用呢? 1. ...
- springMVC的拦截器工作流程
首先,springmvc的拦截器配置在这就不多说了.主要讲一下拦截器的三个方法的执行顺序. preHandle方法一定是最先执行的方法,如果它返回为false下面的方法均不执行. postHandle ...
- SpringMVC—Struts2拦截器学习网址整理
引自:http://blog.csdn.net/wp1603710463/article/details/49982683 SpringMVC—Struts2拦截器学习网址整理 最近项目中遇到权限相关 ...
- 转 :关于springmvc使用拦截器
原博客: http://elim.iteye.com/blog/1750680 SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的 ...
- springmvc中拦截器与springmvc全局异常处理器的问题
最近在做一个练手的小项目, 系统架构中用了springmvc的全局异常处理器, 做了系统的统一异常处理. 后来加入了springmvc的拦截器, 为了一些需求, 在拦截器中的 preHandle 方法 ...
- springMVC配置拦截器、过滤器、前端控制器时遇到的问题总结
1.业务场景:使用vuejs+springMVC+spring框架搭建一个mis系统,集成SSO单点登录: 2.遇到问题:使用interceptor拦截器配置SSO单点登录,直接敲域名,或者ip+端口 ...
随机推荐
- 一种使用 Redis 深度驱动的,为构建轻量级分布式应用程序(Microservices)的工程方案
Hydra 是一个轻量级的 NodeJS 库,用于构建分布式计算应用程序,比如微服务.我们对轻量级的定义是:轻处理外部复杂性和基础设施依赖 -- 而不是有限的轻处理. Hydra 声称对基础设施的依赖 ...
- 推荐系统实践 0x0e LS-PLM
在之前介绍的几个模型中,存在这些问题: LR不能捕捉非线性,只能进行一次的回归预测 GBDT+LR虽然能够产生非线性特征组合,但是树模型不适用于超高维稀疏数据 FM利用二阶信息来产生变量之间的相关性, ...
- 【题解】「SP34013」SEUG - Seetha’s Unique Game
这道题一看就是 贪心 . 使放的石头少,就需要石头大. 那么就可以将石头重量排序,从大到小. 这道题里面看似东西很多,但是很多东西都是没有用的.比如说:箱子的长和宽,因为题目中说「每加一个石头,水的高 ...
- 落谷 P2401 不等数列
题目链接. Solution 状态设计 设 \(f_{i, j}\) 为 \(1\) 到 \(i\) 的排列,其中有 \(j\) 个 \(\text{'<'}\) 的方案数. 状态转移 尝试从 ...
- Acwing 405. 将他们分好队
大型补档计划 题目链接 看到分成两组,想到二分图判定 + 染色. 二分图的特点是两个有矛盾的点连一条边,考虑在这道题中,如果 \(a, b\) 中有一个人不认识对方(或者两个人互不认识),就不可能分在 ...
- java和python的时间格式化区别
java 和 python时间格式化区别 月份,java是M,python是m 分钟,java是m,python是M 年份,必须用yyyy,表示当天所在的年份,如果用YYYY,则表示当前周所在年份 j ...
- STL——容器(List)list 的赋值操作
list.assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身 1 #include <iostream> 2 #include <list> ...
- AWT02-ContainerAPI
1.体系 Object -Component -Container Window:窗口容器 Frame:创建窗口 Dialog:创建对话框 Panel:内嵌容器 Applet ScrollPane:含 ...
- 使用spark将内存中的数据写入到hive表中
使用spark将内存中的数据写入到hive表中 hive-site.xml <?xml version="1.0" encoding="UTF-8" st ...
- create-react-app 基于TS的项目
写在前面 最近在用React,发现百度了很多都没有找到基于TS的React项目搭建,很多是老的方法已经属于不成功的了,今天我把最新的搭建基于ts的React的项目分享出来 create-react-a ...