实现SpringBoot过滤器
在Spring Boot中,过滤器(Filter)是一种用于在请求进入Servlet之前或响应离开Servlet之前执行特定任务的组件。过滤器主要用于对HTTP请求和响应进行全局性的处理,如身份验证、日志记录、字符编码转换等。
作用
- 预处理请求: 过滤器允许在请求到达Servlet之前执行一些操作,如身份验证、请求日志记录等。
- 后处理响应: 在响应离开Servlet之前,过滤器可以执行一些操作,例如修改响应内容、日志记录等。
- 全局任务: 通过过滤器可以实现对所有请求和响应的全局性任务,而无需修改每个Servlet。
接口
在Java Servlet规范中,过滤器是通过实现javax.servlet.Filter
接口来创建的。这个接口定义了三个方法:
init(FilterConfig config)
: 在过滤器被初始化时调用,可以进行一些初始化操作。doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
: 执行过滤器的实际逻辑。在这里可以对请求或响应进行处理,然后通过FilterChain
继续执行下一个过滤器或Servlet。destroy()
: 在过滤器被销毁时调用,可以进行一些资源释放操作。
注册
在Spring Boot中,可以通过两种方式注册过滤器:
FilterRegistrationBean
: 通过配置类,创建FilterRegistrationBean
并设置相关属性,然后将其注册到Spring容器中。@WebFilter
注解: 直接在过滤器类上使用@WebFilter
注解,指定过滤器的名称和URL模式。
执行顺序
过滤器可以设置执行顺序,确保它们按照期望的顺序执行。通过设置FilterRegistrationBean
的order
属性或在过滤器类上使用@Order
注解来实现。
示例
/**
* 检查用户是否已经完成登录
*/
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter {
//路径匹配器,支持通配符
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest; //向下转型
HttpServletResponse response = (HttpServletResponse) servletResponse;
//定义不需要处理的请求路径
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**",
};
//1、获取本次请求的URI_
String requestURI = request.getRequestURI();
log.info("拦截到请求:{}",requestURI);
//2、判断本次请求是否需要登录
boolean check = check(urls, requestURI);
//3、如果不需要登录,直接放行
if (check){
log.info("本次请求{}不需要处理",requestURI);
filterChain.doFilter(request, response);
return;
}
//4、如果需要登录,判断登录状态,如果已登录,直接放行
if(request.getSession().getAttribute("employee") != null){
log.info("用户已登录,用户id为:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request, response);
return;
}
//5、如果未登录,返回未登录结果,通过输出流方式向客户端页面响应数据
log.info("用户未登录");
response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
return;
}
/**
* 路径匹配,检查本次请求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match){
return true;
}
}
return false;
}
}
实现过程:
获取HttpServletRequest
和HttpServletResponse
: 在doFilter
方法中,首先将ServletRequest
和ServletResponse
转型为HttpServletRequest
和HttpServletResponse
,以便获取请求和响应的详细信息。
定义不需要登录检查的路径: 使用字符串数组urls
定义了一些不需要登录检查的路径,包括登录和登出接口,以及一些特定的后端和前端路径。
获取当前请求的URI: 通过HttpServletRequest
获取当前请求的URI。
路径匹配检查: 使用check
方法进行路径匹配检查,判断当前请求路径是否在不需要登录检查的列表中。如果是,直接放行。
用户登录状态检查:
- 如果用户已登录,放行。
- 如果用户未登录,通过
HttpServletResponse
的输出流向客户端响应一个JSON格式的错误消息,提示用户未登录。
其中,
-
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
: 使用@WebFilter
注解标识该类为过滤器,指定过滤器的名称为"loginCheckFilter",并将其应用到所有路径(“/*”)。 -
使用
AntPathMatcher
实例作为路径匹配器,支持通配符,用于匹配请求路径。
在Spring Boot应用的主类上使用@ServletComponentScan
注解,以启用Servlet组件的自动扫描。
@Slf4j
@SpringBootApplication
@ServletComponentScan
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class);
log.info("项目启动成功");
}
}