【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+端口 ...
随机推荐
- AGC043 B题题解
有的时候,碰到一道题,要给自己先设立部分分,再去想如何把部分分推广到一般情况.这题就是绝佳的例子. 不妨将\(a_i\)用\(a_i - 1\)替代,这样就变成了\(a_i \in \{ 0, 1, ...
- Springboot mini - Solon详解(六)- Solon的校验框架使用、定制与扩展
Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...
- GaussDB(DWS)应用实践丨负载管理与作业排队处理方法
摘要:本文用来总结一些GaussDB(DWS)在实际应用过程中,可能出现的各种作业排队的情况,以及出现排队时,我们应该怎么去判断是否正常,调整一些参数,让资源分配与负载管理更符合当前的业务:或者在作业 ...
- JavaSE06-面向对象
1. 类和对象 1.1 类和对象的理解 客观存在的事物皆为对象 ,所以我们也常常说万物皆对象. 类 类的理解 类是对现实生活中一类具有共同属性和行为的事物的抽象 类是对象的数据类型,类是具有相同属性和 ...
- Collections.synchronizedList 并发
1.背景 集合类中的map,大家一定熟悉,知道它非线程安全.使用的方法有两种,一种是在map上加同步器(锁),另一种是创建容器时使用Collections中的静态方法对map进行包装. java ap ...
- css 05-CSS样式表的继承性和层叠性
05-CSS样式表的继承性和层叠性 #本文重点 CSS的继承性 CSS的层叠性 计算权重 权重问题大总结 CSS样式表的冲突的总结 权重问题深入 同一个标签,携带了多个类名 !important标记 ...
- react第X单元(redux)
第X单元(redux) #课程目标 理解redux解决的问题,理解redux的工作原理 熟练掌握redux的api 熟练掌握redux和react组件之间的通信(react-redux) 把redux ...
- [日常摸鱼]bzoj1444 [JSOI2009]有趣的游戏——AC自动机+矩阵
今天学校跳蚤市场摆摊聚众吸毒打call,东西卖了一百多好开心_(:з」∠)_ (然后大家中午就去吃了一顿好的x) 下午听演讲然后现在来填坑orz(其实是昨晚的坑) 题目:bzoj1444 先用字符串构 ...
- Eureka系列(三)获取服务Client端具体实现
获取服务Client 端流程 我们先看下面这张图片,这张图片简单描述了下我们Client是如何获取到Server已续约实例信息的流程: 从图片中我们可以知晓大致流程就是Client会自己开启一个 ...
- php 文件上传错误
假设文件上传字段的名称img,则: $_FILES['img']['error']有以下几种类型 1.UPLOAD_ERR_OK 其值为 0,没有错误发生,文件上传成功. 2.UPLOAD_ERR_I ...