笔记大纲
- 拦截器简介
- 单个拦截器
- 两个拦截器preHandle()方法测试
- 小结
- 图解
拦截器简介
Spring MVC可使用拦截器对请求进行拦截处理,用户也可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor
接口,也可以继承HandlerInterceptorAdapter
适配器类 。
HandlerInterceptor
接口中主要实现的方法:
主要方法 | 说明 |
---|---|
preHandle() | 在业务处理器处理请求之前被调用,在该方法中对用户请求 request 进行处理。 如果该拦截器对请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回 true ;反之不需要再调用其他的组件去处理请求,则返回false 。 |
postHandle () | 在业务处理器处理完请求后(没有渲染视图),但是DispatcherServle 向客户端返回响应前被调用 ,也是对用户请求 request 进行处理。 |
afterCompletion () | 在 DispatcherServlet 完全处理完请求后被调用(已经渲染了视图) ,可方法中进行一些资源清理的操作。 |
1.单个拦截器
(1)工程结构
(2)MyFirstInterceptor拦截器
@Component`注解表明是拦截器组件!
preHandle()
方法返回
return true;
package com.codinglin.springmvc.interceptors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
/*
* 拦截器案例
*/
@Component
public class MyFirstInterceptor implements HandlerInterceptor {
/*
* 在 DispatcherServlet完全处理完请求后被调用
*/
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println(this.getClass().getName()+"========测试afterCompletion============");
}
/*
* 在业务处理器处理请求之后被调用
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println(this.getClass().getName()+"========测试postHandle============");
}
/*
* 在业务处理器处理请求之前被调用
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
// return true;表示请求继续提交 return false;表示请求不再提交
System.out.println(this.getClass().getName()+"========测试preHandle============");
return true;
}
}
(3)TestController处理器
package com.codinglin.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class TestController {
@RequestMapping("test")
public String test() {
System.out.println("调用test处理器的方法");
return "success";
}
}
(4)测试入口页面index.jsp
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试入口页面</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/test">拦截器测试器</a>
</body>
</html>
(4)WEB-INF下web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
(5)类路径下的spring-mvc.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"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 组件扫描 -->
<context:component-scan base-package="com.codinglin.springmvc"/>
<!-- 视图解析器 -->
<bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 注册拦截器 -->
<mvc:interceptors>
<!-- 拦截通过中央调度器过滤所有请求 -->
<bean id="myFirstInterceptor"
class="com.codinglin.springmvc.interceptors.MyFirstInterceptor">
<!-- <ref bean="myFirstInterceptor"/> -->
</bean>
</mvc:interceptors>
</beans>
运行效果:
☛注意:如果MyFirstInterceptor没有标记注解,则报错!
2.多个拦截器
(1)新建MySecondInterceptor拦截器
@Component
注解表明是拦截器组件!
preHandle()
方法返回return true;
package com.codinglin.springmvc.interceptors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component
public class MySecondInterceptor implements HandlerInterceptor {
/*
* 在 DispatcherServlet完全处理完请求后被调用
*/
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println(this.getClass().getName()+"========测试afterCompletion02============");
}
/*
* 在业务处理器处理请求之后被调用
*/
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println(this.getClass().getName()+"========测试postHandle02============");
}
/*
* 在业务处理器处理请求之前被调用
*/
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
// return true;表示请求继续提交 return false;表示请求不再提交
System.out.println(this.getClass().getName()+"========测试preHandle02============");
return true;
}
}
(2)修改类路径下的spring-mvc.xml文件
拦截器注册时先后顺序会影响preHandle()调用的顺序!
<!-- 注册拦截器 -->
<mvc:interceptors>
<!-- 拦截通过中央调度器过滤所有请求 -->
<bean id="myFirstInterceptor" class="com.codinglin.springmvc.interceptors.MyFirstInterceptor" />
<!-- <ref bean="myFirstInterceptor"/> 用注解方式替换-->
<!-- 配置拦截器,指定拦截请求 -->
<mvc:interceptor>
<!-- 一定要指定拦截谁 ,注意先后顺序!!!-->
<mvc:mapping path="/test"/>
<!-- <mvc:exclude-mapping path=""/> -->
<bean id="mySecondInterceptor" class="com.codinglin.springmvc.interceptors.MySecondInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
运行效果:
MyFirstInterceptor和MySecondInterceptor类中的
preHandle()
方法都返回的true
!
3.两个拦截器preHandle()方法返回值测试
(1)一个true,一个false
(2)一个false,一个true
(3)一个false,一个false
4.日常小结
多个拦截器的执行顺序及方法的执行情况:
(1)多个拦截器的执行顺序 : 根据配置顺序来决定,先配置的先执行;
(2)方法的执行情况:
①preHanle: 与拦截器的执行顺序一致
②postHandle: 与拦截器的执行顺序相反
③afterCompletion: 与拦截器的执行顺序相反
preHandle()方法的返回值:
(1)返回true代表请求可以正常往后执行
(2)返回false,代表请求被拦截住,不能继续往后执行
①如果是第一个拦截器的preHandle返回false,则后续的操作都不执行;
②如果不是第一个拦截器的preHandle返回false, 之前拦截器的preHandle以及afterCompletion都会执行。
5.图解
第一种情况:
第二种情况:
☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!
☞本人博客:https://coding0110lin.blog.csdn.net/ 欢迎转载,一起技术交流吧!