Filter
- 可以把资源请求拦截下来,从而实现一些特殊功能
- 什么是特殊功能
过滤器一般完成通用的操作,比如:权限控制,统一编码处理,敏感字处理
- 例如访问资源: 没登陆,过滤器直接提示没登陆返回重新登陆
操作方法
见fristlearn
- filterChain.doFilter(servletRequest,servletResponse); 放行
操作逻辑
- 放行前
- 放行后
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("放行前..."); filterChain.doFilter(servletRequest,servletResponse); System.out.println("放行后...");
执行流程
如果访问对应资源访问资源完毕,回到FIlter中是重新执行还是执行放行后的逻辑呢
答:是执行放行后
执行放行前逻辑 -> 放行 -> 访问资源 -> 执行放行后逻辑(对Responce的数据进行处理)
Filter 使用细节
- Filter拦截路径配置
- 过滤器链
import jakarta.servlet.annotation.WebFilter;
@WebFilter("/xxx");
拦截路径
- 拦截具体的资源: /index.jsp
- 目录拦截: /user/* 访问/user 下的所有资源,都会被拦截
- 后缀名拦截: *.jsp 访问所有后辍名为jsp的资源都会被拦截
- 拦截所有: /* 访问所有资源都会被拦截
过滤链
- 一个Web应用,可以配置多个过滤器,这多个过滤器成为过滤链
- 详情见Second
执行流程
1.Gets 3.Get 5.111 4.Haha 2.OK
过滤器顺序:
- 注解配置的Filter , 优先级按照过滤器类名(字符串)的自然排序
案例 登陆验证
- 需求:访问服务器资源时,需要进行的登陆验证
- 判断是否用户登陆: session中是否有user对象
- 登陆:直接放行
- 未登录:跳转到登陆界面,并给出提示信息
package com.example.learn_filter.login.filter;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.constraints.Null;
import java.io.IOException;
@WebFilter("/*")
public class Filter implements jakarta.servlet.Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
jakarta.servlet.Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpSession session = req.getSession();
/* 需要放行 的登陆 */
String [] urls = {"/login"};
String url = req.getRequestURI().toString();
for (String u : urls){
if (url.contains(u)){
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
/*===============*/
String username = (String) session.getAttribute("username");
System.out.println("拦截: " + username +".");
if(username != null){
filterChain.doFilter(servletRequest, servletResponse);
}else{
req.setAttribute("login_msg","您尚未登陆");
req.getRequestDispatcher("login.html").forward(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
jakarta.servlet.Filter.super.destroy();
}
}