抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

摘要:本文介绍了Spring MVC中的过滤器。

环境

Windows 10 企业版 LTSC 21H2
Java 1.8
Tomcat 8.5.50
Maven 3.6.3
Spring 5.3.23

1 概述

过滤器(Filter)是JavaWeb中的一种组件,用于在请求到达Servlet之前或响应返回客户端之前对请求和响应进行处理。

2 使用方式

在JavaWeb中注册过滤器有以下两种方式:

  • 通过@WebFilter注解注册过滤器,只能注册自定义过滤器。
  • 通过web.xml配置文件注册过滤器,可以注册内置过滤器和自定义过滤器。

在Spring MVC中还可以通过配置类代替web.xml配置文件注册过滤器,可以注册内置过滤器和自定义过滤器。

3 获取容器

3.1 手动获取

默认情况下,过滤器是在Web容器中运行的,无法直接获取核心容器中的对象,需要使用WebApplicationContextUtils工具类获取。

使用WebApplicationContextUtils工具类获取核心容器,再通过核心容器获取对象。

3.1.1 注册根配置类

3.1.1.1 半注解配置

web.xml配置文件中配置过滤器:

web.xml
1
2
3
4
5
6
7
8
9
10
<!-- 配置过滤器 -->
<filter>
<filter-name>demoFilter</filter-name>
<filter-class>com.example.filter.DemoFilter</filter-class>
</filter>
<!-- 配置过滤器的URL模式 -->
<filter-mapping>
<filter-name>demoFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

web.xml配置文件中配置核心监听器:

web.xml
1
2
3
4
5
6
7
8
9
<!-- 配置核心监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置核心容器的根配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>

根配置文件:

spring.xml
1
2
3
4
5
6
7
8
9
10
11
<?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"
xsi:schemaLocation="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.xsd">
<!-- 启用对象扫描,排斥Web配置文件中的对象 -->
<context:component-scan base-package="com.example">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
3.1.1.2 全注解配置

在Web初始化类中配置过滤器:

java
1
2
3
4
5
@Override
protected Filter[] getServletFilters() {
DemoFilter demoFilter = new DemoFilter();
return new Filter[] {demoFilter};
}

在Web初始化类中配置根配置类:

java
1
2
3
4
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {RootConfig.class};
}

根配置类:

java
1
2
3
4
5
6
7
@Configuration
@ComponentScan(
basePackages = "com.example",
excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class)
)
public class RootConfig {
}

3.1.2 获取容器对象

通过WebApplicationContextUtils工具类获取核心容器中的对象:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class DemoFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 获取核心容器
WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
// 使用核心容器获取对象
DemoService demoService = context.getBean(DemoService.class);
// 记录日志
System.out.println(demoService);
// 继续执行过滤器链
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}

3.2 自动注入

如果想在过滤器中自动注入核心容器中的对象,可以使用DelegatingFilterProxy类代理过滤器:

  1. 将过滤器注册到核心容器。
  2. 使用DelegatingFilterProxy代理核心容器中的过滤器,支持web.xml配置文件和配置类两种方式配置代理过滤器。

3.2.1 注册过滤器

自定义过滤器,并注册到核心容器中:

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component
public class DemoFilter implements Filter {
@Resource
DemoService demoService;
@Override
public void init(FilterConfig config) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 记录日志
System.out.println(demoService);
// 继续执行过滤器链
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}

3.2.2 代理过滤器

3.2.2.1 半注解配置

使用配置文件注册代理过滤器:

web.xml
1
2
3
4
5
6
7
8
<filter>
<filter-name>demoFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>demoFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

需要设置filter-name标签的值与自定义过滤器在核心容器中的名称一致,如果不一致,需要在filter标签中使用init-param标签指定自定义过滤器的名称。

指定自定义过滤器的名称:

web.xml
1
2
3
4
5
6
7
8
9
10
11
12
<filter>
<filter-name>demoFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>demoFilter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>demoFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
3.2.2.2 全注解配置

使用配置类注册代理过滤器:

java
1
2
3
4
5
6
7
8
9
@Override
protected Filter[] getServletFilters() {
// 注册代理过滤器,指定自定义过滤器在核心容器中的名称
DelegatingFilterProxy delegatingFilter = new DelegatingFilterProxy("demoFilter");
// 代理管理目标过滤器的生命周期
delegatingFilter.setTargetFilterLifecycle(true);
// 返回过滤器
return new Filter[]{delegatingFilter};
}

评论