【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+端口 ...
随机推荐
- NOI Online 题解
T1 对\(t_i = 1\)的边,将\(u_i, v_i\)连一条边权为\(1\)的边.否则连一条边权为\(0\)的边. 对于每一个连通块,若图中不存在一条边权之和为奇数的圈,则可以将这个连通块二染 ...
- STL——容器(Set & multiset)的概念和特点
1. Set 和 multiset 的概念 set 和 multiset 是一个集合容器,其中 set 所包含的元素是唯一的,集合中的元素按一定的顺序排列.set 采用红黑树变体的数据结构实现,红黑树 ...
- JQuery统一复写美化项目中所有radio单选按钮样式
老项目要升级改版,对于分散在各页面的样式不好处理,怕有遗漏,尤其是优化input表单,修改其默认样式,接下来,我将给大家分享一下,我在项目中的总结. 效果 上代码: 1.简单搞一搞 CSS,此处代码有 ...
- GaussDB(DWS)应用实践丨负载管理与作业排队处理方法
摘要:本文用来总结一些GaussDB(DWS)在实际应用过程中,可能出现的各种作业排队的情况,以及出现排队时,我们应该怎么去判断是否正常,调整一些参数,让资源分配与负载管理更符合当前的业务:或者在作业 ...
- MySQL02-约束
1.DQL查询语句 1.1 排序查询 语法:order by 排序字段1 排序方式1 , 排序字段2 排序方式2... 排序方式: ASC:升序,默认的. DESC:降序. 注意: 如果有多个排序条 ...
- Numpy的学习2-基础转换
import numpy as np A = np.arange(2, 14).reshape((3, 4)) # array([[ 2, 3, 4, 5] # [ 6, 7, 8, 9] # [10 ...
- 微服务之服务治理_Eureka
首先需要明确,不管是什么事物需要"治理",那一定是该事物存在一定问题.比如环境治理.那么服务,或者说微服务为什么需要治理?对于服务来说,如果它承担的业务职责简单,那其实治理的必要性 ...
- CSS —— css属性
1.颜色属性 background-color: #CCCCCC; rgba (红色,绿色,蓝色,透明度) background-color: rgba( 0, 0, 0, 5 ) 2.字体属性 fo ...
- Spring Cloud Alibaba基础教程-Nacos(三)
在Spring Cloud Alibaba基础教程-Nacos(二)当中学习了,如何使用 nacos图形化界面操作 ,使用Nacos部署集群,下面我们开始Nacos最后一篇的学习 ,如果对你有帮助,记 ...
- Blogs实现导航菜单
#1.隐藏默认导航菜单 #header{display:none;} /*在页面定制CSS里面最前面添加如下代码,最好添加在最前面*/ #2.添加页首html代码 <!-- 添加博客导航栏信息开 ...