携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
Servlet规范中有3个非常特殊的Servlet,分别是过滤器、监听器和拦截器,如果使用得当,利用它们可以简单地完成一般Servlet才能实现的烦琐功能。本文介绍过滤器。
过滤器简介
Java中的过滤器是一种特殊的Servlet,它不能处理用户请求,也不能为客户端生成响应信息,它主要用于对HttpServletRequest进行前处理,也可以对HttpServletResponse进行后处理,是一个典型的处理链程序。
过滤器(Filter)放在Web资源之前,可以在前端请求抵达Web资源之前被截获,并且还可以在资源返回客户之前截获输出的请求。过滤器是用来拦截请求的,处于客户端与被请求资源之间,目的是重用代码。在一个项目中可以配置多个过滤器,一个请求会依次通过配置的所有过滤器。
Web项目常用的过滤器有以下3种:
- 用户授权的过滤器:负责检查用户请求,根据请求信息过滤用户的非法请求。
- 日志过滤器:详细记录某些特殊的用户请求。
- 负责编码/解码的过滤器:对请求参数的编码和解码。
过滤器实践
Spring Web提供了很多过滤器,这些过滤器都在org.springframework.web.filter包中,全部实现了javax.servlet.Filter接口。如果项目中需要自定义过滤器,有以下4种实现方式: 直接实现Filter接口。
- 继承抽象类GenericFilterBean,此类已经实现了javax.servlet.Filter接口,是普通的Filter实现。
- 继承抽象类OncePerRequestFilter,此类是GenericFilterBean的直接子类,主要用于对请求参数的处理。
- 继承抽象类AbstractRequestLoggingFilter,该类为OncePerRequestFilter的直接子类,主要用于处理日志过滤。
- 自定义过滤器。
下面实现一个自定义的过滤器,过滤请求URL为/test1的请求。如果是这个请求,则打印这个请求的所有参数并直接返回不再继续处理业务,否则直接放行。首先实现一个自定义的Filter,代码如下:
package com.example.thymeleafdemo.filter;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
/**
* 自定义过滤器的实现
*/
@Component
public class MyHttpFilter implements Filter {
/**
* 过滤方法
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, Servlet
Exception {
HttpServletRequest servletRequest = (HttpServletRequest) request;
String requestURI = servletRequest.getRequestURI();
if ("/test1".equals(requestURI)) {
Map<String, String[]> map = servletRequest.getParameterMap();
for (Map.Entry<String, String[]> entry : map.entrySet()) {
System.out.println("请求的参数名字是:" + entry.getKey()
+ " ,请求的值是:" + Arrays.toString(entry.getValue()));
return;
}
}
//放行,继续后面的业务处理
chain.doFilter(servletRequest,response);
}
}
在UserController.java文件中添加test1方法的代码如下:
@ResponseBody
@GetMapping("/test1")
public String test1(){
return "success";
}
过滤器使用场景:
- 执行目标资源之前执行预处理,如设置编码;
- 通过条件判断是否放行,如校验当前用户是否已经登录,或某些用户的IP是否被禁用;
- 目标资源执行后,后续的特殊处理工作,如处理目标资源输出的数据。