目录
一、概念
二、自定义拦截器的三个实现方法
三、自定义拦截器执行流程
四、使用
五、拦截器和过滤器
相关文章(可以关注我的SpringMVC专栏)
SpingMVC专栏 | SpingMVC专栏 |
一、概念
在学习拦截器之前,我们得先了解一下它是个什么❓
SpringMVC可以通过拦截器
对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能。
如何实现自定义的拦截器❓
自定义的拦截器必须实现HandlerInterceptor
。
二、自定义拦截器的三个实现方法
preHandle()
:这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request 进行处理。postHandle()
:这个方法在目标方法处理完请求后执行。afterCompletion()
:这个方法在完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作。
到这里不知道大家有没有发现,这个SpringMVC中的拦截器
和我们学Servlet时的Filter
过滤器有点像。至于这个问题我们后边说到。
三、自定义拦截器执行流程图
自定义拦截器执行流程说明:
- 如果
preHandle
方法 返回 false, 则不再执行目标方法, 可以在此指定返回页面。 postHandle
在目标方法被执行后执行。可以在方法中访问到目标方法返回的ModelAndView 对象。- 若
preHandle
返回 true, 则afterCompletion
方法 在渲染视图之后被执行。 - 若
preHandle
返回 false, 则afterCompletion
方法不会被调用。 - 在配置拦截器时,可以指定该拦截器对哪些请求生效,哪些请求不生效。
四、使用
前端
<%--
Created by IntelliJ IDEA.
User: huawei
Date: 2022/11/30
Time: 21:42
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>测试自定义拦截器</title>
</head>
<body>
<h1>测试自定义拦截器</h1>
<a href="<%=request.getContextPath()%>/hi">测试拦截器</a>
<a href="<%=request.getContextPath()%>/hello">测试拦截器</a>
</body>
</html>
后端
拦截器1
package com.jl.web.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* ClassName: MyInterceptor
* Package: com.jl.web.interceptor
* Description: 演示自定义拦截器
*
* @Author: Long
* @Create: 2022/11/30 - 21:32
* @Version: v1.0
*/
@Component
public class MyInterceptor01 implements HandlerInterceptor {
/**
* 该方法在目标方法执行前执行,如果该方法返回false,就不再执行目标方法
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterception01----preHandle");
return true;
}
/**
* 在目标方法执行后会执行该方法
* 该方法可以获取到 目标方法返回的 ModelAndView
* @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("MyInterception----postHandle");
}
/**
* 在视图渲染后执行
* 在这里可以做一些资源清理工作
* @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("MyInterception----afterCompletion");
}
}
拦截器2
package com.jl.web.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* ClassName: MyInterception
* Package: com.jl.web.interceptor
* Description:
*
* @Author: Long
* @Create: 2022/11/30 - 22:13
* @Version: v1.0
*/
@Component
public class MyInterceptor02 implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("-----MyInterception02----preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("-----MyInterception02----postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("-----MyInterception02----afterCompletion");
}
}
请求的目标Handler
package com.jl.web.interceptor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* ClassName: FurnHandler
* Package: com.jl.web.interceptor
* Description:
*
* @Author: Long
* @Create: 2022/11/30 - 21:40
* @Version: v1.0
*/
@Controller
public class FurnHandler {
@RequestMapping(value = "/hi")
public String hi(){
System.out.println("----FurnHandler---hi");
return "success";
}
@RequestMapping(value = "/hello")
public String hello(){
System.out.println("----FurnHandler---hello");
return "success";
}
}
我们的Handler中提供了两个处理方法。
配置自定义拦截器
<!--配置自定义拦截器-->
<mvc:interceptors>
<!--第一种配置方式
直接使用 ref 引用到对应的 myInterceptor01
这种方式会拦截所有的目标方法
-->
<!--<ref bean="myInterceptor01"/>-->
<!--第二种配置方式
mvc:mapping path="/hi/" 指定要拦截的路径
ref bean="myInterceptor01" 指定对哪个拦截器进行配置
-->
<!--<mvc:interceptor>-->
<!-- <mvc:mapping path="/hi"/>-->
<!-- <ref bean="myInterceptor01"/>-->
<!--</mvc:interceptor>-->
<!--第三种配置方式
支持通配符
<mvc:mapping path="/h*"/> h开头的目标方法全部拦截
<mvc:exclude-mapping path="/hello"/> 不拦截 /hello 路径
-->
<mvc:interceptor>
<mvc:mapping path="/h*"/>
<mvc:exclude-mapping path="/hello"/>
<ref bean="myInterceptor01"/>
</mvc:interceptor>
<!--配置第二个拦截器
当有多个拦截器,是按照配置顺序来执行的
-->
<mvc:interceptor>
<mvc:mapping path="/h*"/>
<ref bean="myInterceptor02"/>
</mvc:interceptor>
</mvc:interceptors>
我们这种配置是:拦截器1只拦截hi
,而拦截器2hi
和hello
都拦截。
下边我们看一下结果:
请求hi
两个拦截器都生效。
请求hello
只有拦截器2生效。
五、拦截器和过滤器
它们的区别大家可以参考此篇文章:
👉拦截器与过滤器的区别
如果文章中有描述不准确或者错误的地方,还望指正。您可以留言📫或者私信我。🙏
最后希望大家多多 关注+点赞+收藏^_^,你们的鼓励是我不断前进的动力!!!
感谢感谢~~~🙏🙏🙏