用户授权、日志记录、编码解码、UA分析、多端应用等都需要拦截请求来进行处理。这时就需要 Servlet
、Filter
、Listener
、Interceptor
这几种组件。本章主要讲解Filter
的用法。
Filter
对用户请求进行预处理,接着将请求交给Servlet
进行处理并生成响应,最后Filter
再对服务器响应进行后处理。Filter
是可以复用的代码片段,常用来转换 HTTP 请求、响应和 头信息。Filter
不像Servlet
,它不能产生响应,而是只修改对某一资源的请求或者响应。
一、自定义过滤器
这里模拟登陆过程:拦截所有的请求,放行登录页面,其余请求全部重定向到登陆界面。同时配置参数,指定要放行的路径和请求的字符集。
public class LoginFilter implements Filter {
private FilterConfig config;
@Override
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
// 获取配置参数
String loginUI = config.getInitParameter("loginUI");
String encoding = config.getInitParameter("encoding");
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 设置请求的字符集(post请求方式有效)
request.setCharacterEncoding(encoding);
// 不带http://域名:端口的地址
String uri = request.getRequestURI();
if (uri.contains(loginUI)) {
// 请求的登录,放行
chain.doFilter(request, response);
} else {
// 重定向到登录页面
response.sendRedirect(request.getContextPath() + loginUI);
}
}
@Override
public void destroy() {
this.config = null;
}
}
当LoginFilter
初始化时,会执行init()
方法。每次请求路径匹配urlPatterns
配置的路径时,就会进入doFilter()
方法进行具体的请求和响应过滤。
当HTTP请求路径包含/home/loginUrl
时,请求会被放行;否则,直接重定向到首页,结束请求处理。
doFilter的参数说明:
1. ServletRequest: 未到达 Servlet 的 HTTP 请求
2. ServletResponse: 由 Servlet 处理并生成的 HTTP 响应
3. FilterChain: 过滤器链对象,可以按顺序注册多个过滤器
一个过滤器链对象可以按顺序注册多个过滤器。符合当前过滤器过滤条件,即请求过滤成功直接放行,则交由下一个过滤器进行处理。
所有请求过滤完成以后,由IndexHttpServlet
处理并生成响应,然后在过滤器链以相反的方向对响应进行后置过滤处理。
二、注册过滤器
1. 通过@WebFilter
配置
在自定义的过滤器上添加@WebFilter
。
@WebFilter(filterName = "loginFilter",
urlPatterns = "/*",
initParams = {
@WebInitParam(name = "loginUI", value = "/home/loginUrl"),
@WebInitParam(name = "encoding", value = "UTF-8")
})
@Order(1) //过滤顺序
@WebFilter常用属性
属性 | 类型 | 是否必需 | 说明 |
asyncSupported | boolean | 否 | 指定Filter是否支持异步模式 |
dispatcherTypes | DispatcherType[] | 否 | 指定Filter对哪种方式的请求进行过滤。支持的属性:ASYNC、ERROR、FORWARD、INCLUDE、REQUEST;默认过滤所有方式的请求 |
filterName | String | 否 | Filter名称 |
initParams | WebInitParam[] | 否 | 配置参数 |
displayName | String | 否 | Filter显示名 |
servletNames | String[] | 否 | 指定对哪些Servlet进行过滤 |
urlPatterns/value | String[] | 否 | 两个属性作用相同,指定拦截的路径 |
注意: 添加此注解的类必须得在启动类的扫描目录下
2. 通过注册配置类使用过滤器
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean someFilterRegistration1() {
//新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean();
// 添加我们写好的过滤器
registration.setFilter( new LoginFilter());
// 设置过滤器的URL模式
registration.addUrlPatterns("/*");
// 设置过滤器配置参数
registration.addInitParameter("loginUI", "/home/loginUrl");
registration.addInitParameter("encoding", "UTF-8");
// 设置过滤器名称
registration.setName("loginFilter");
//设置过滤顺序,从小到大依次执行
registration.setOrder(1);
return registration;
}
}
注意: 此配置类必须得在启动类的扫描目录下
3. web.xml
以上两种配置Spring Boot的常用使用,其对应的xml配置如下:
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.simon.filter.LoginFilter</filter-class>
<init-param>
<param-name>loginUI</param-name>
<param-value>/home/loginUrl</param-value>
</init-param>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>