| 动态地拦截请求和响应,变换或使⽤包含在请求或响应中的信息 |
| 在客户端的请求访问后端资源之前,拦截这些请求 |
| 在服务器的响应发送回客户端之前,处理这些响应 |
| init(FilterConfig filterConfig) |
| doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 只要命中 |
| 过滤规则就触发,可以在filter中根据条件决定是否调⽤chain.doFilter(request, response)⽅ |
| 法, 即是否让⽬标资源执⾏ |
| destroy() |
| package jakarta.servlet; |
| |
| import java.io.IOException; |
| |
| public interface Filter { |
| default void init(FilterConfig filterConfig) throws ServletException { |
| } |
| |
| void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; |
| |
| default void destroy() { |
| } |
| } |
- 自定义filter时,使用@WebFilter的参数
| |
| asyncSupported |
| |
| Forward,include,request |
| dispatcherType |
| |
| displayName |
| |
| filterName |
| |
| initParams |
| |
| servletNames |
| |
| 加*,应该按照模块划分,⽐如/user |
| |
| |
| @WebFilter(filterName = "testFilter",urlPatterns = {"/*"}) |
| public class CustomFilter implements Filter { |
| |
| |
| |
| |
| |
| |
| @Override |
| public void init(FilterConfig filterConfig) throws ServletException { |
| System.out.println("CustomFilter init "); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| @Override |
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
| System.out.println("CustomFilter doFilter "); |
| request.setCharacterEncoding("UTF-8"); |
| response.setCharacterEncoding("UTF-8"); |
| response.setContentType("text/html;charset=utf-8"); |
| |
| chain.doFilter(request,response); |
| } |
| |
| |
| |
| |
| @Override |
| public void destroy() { |
| System.out.println("CustomFilter destroy "); |
| } |
| |
| } |
| |
| Connected to server |
| [2022-04-14 11:12:36,794] Artifact web06:war exploded: Artifact is being deployed, please wait... |
| 14-Apr-2022 11:12:37.891 警告 [RMI TCP Connection(2)-127.0.0.1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom 使用[SHA1PRNG]创建会话ID生成的SecureRandom实例花费了[574]毫秒。 |
| CustomFilter init |
- 自定义的filter拦截了所有请求,任意访问一个请求,控制台打印如下,说明filter执行了拦截,并放行
| http://localhost:8081/get_cookie_test |
| |
| CustomFilter doFilter |
| null |
| JSESSIONID |
| 47797EAAB1641E2992D93DD3E33C5B21 |
| package jakarta.servlet; |
| |
| import java.util.Enumeration; |
| |
| public interface FilterConfig { |
| String getFilterName(); |
| |
| ServletContext getServletContext(); |
| |
| String getInitParameter(String var1); |
| |
| Enumeration<String> getInitParameterNames(); |
| } |
- dispatcherTypes参数: 指定Filter对那种dispatcher模式进⾏过滤,不符合的则不进⾏过滤
| REQUEST:默认值,浏览器直接请求的资源会被过滤器拦截 |
| FORWARD:转发访问资源会被过滤器拦截 |
| INCLUDE:包含访问资源 |
| ERROR:错误跳转资源 |
| ASYNC:异步访问资源 |
| # 编写CustomFilterTest:设置filter名称,要拦截的url,初始化配置,要拦截的类型 |
| # DispatcherType.FORWARD表示转发的时候被拦截 |
| @WebFilter(filterName = "filterTest",urlPatterns = {"/*"},initParams = { |
| @WebInitParam(name = "encoding",value = "UTF-8"), |
| @WebInitParam(name = "loginPage",value = "/login.jsp"), |
| },dispatcherTypes = {DispatcherType.FORWARD}) |
| |
| # 编写如下,可在filter的重写的方法中使用默认的属性 |
| private FilterConfig filterConfig; |
| private String encoding; |
| private String loginPage; |
| # 发送一个默认的请求http://localhost:8081/get_cookie_test,控制台打印如下,说明没有进入filter, |
| null |
| JSESSIONID |
| B7AAFF00C73C44DE9ECD1F5FB53681C5 |
| |
| # 发送一个转发的请求http://localhost:8081/forward,控制台打印如下,说明转发类型的请求被拦截了 |
| DispatchServlet doGet |
| CustomFilter doFilter |
filter进行登录拦截

| @WebFilter(filterName = "loginFilter",urlPatterns = {"/user/*","/order/*"},initParams = { |
| @WebInitParam(name = "encoding",value = "UTF-8"), |
| @WebInitParam(name = "loginPage",value = "/login.jsp"), |
| }) |
| public class LoginFilter implements Filter { |
| |
| private FilterConfig filterConfig; |
| |
| private String encoding; |
| |
| private String loginPage; |
| |
| |
| |
| |
| |
| |
| @Override |
| public void init(FilterConfig filterConfig) throws ServletException { |
| System.out.println("CustomFilter init "); |
| this.filterConfig = filterConfig; |
| this.encoding = filterConfig.getInitParameter("encoding"); |
| this.loginPage = filterConfig.getInitParameter("loginPage"); |
| } |
| |
| @Override |
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
| System.out.println("CustomFilter doFilter "); |
| request.setCharacterEncoding(encoding); |
| response.setCharacterEncoding(encoding); |
| response.setContentType("text/html;charset=utf-8"); |
| HttpServletRequest httpServletRequest = (HttpServletRequest)request; |
| HttpServletResponse httpServletResponse = (HttpServletResponse)response; |
| |
| if(httpServletRequest.getSession().getAttribute("loginUser") !=null){ |
| |
| chain.doFilter(request,response); |
| }else { |
| httpServletRequest.setAttribute("msg","非法访问,请登录"); |
| httpServletRequest.getRequestDispatcher(loginPage).forward(httpServletRequest,httpServletResponse); |
| } |
| } |
| |
| |
| |
| |
| @Override |
| public void destroy() { |
| System.out.println("CustomFilter destroy "); |
| } |
| |
| } |
- 测试,访问登录页面

- 输入正确的用户名和密码,跳转到user.jsp,控制台打印如下,说明先请求先进入filter初始化 -> loginServlet -> filter过滤器的doFilter()方法
| loginServlet doPost |
| CustomFilter doFilter |

- 退出登录或未登录状态下直接访问user.jsp,访问失败
| http://localhost:8081/user/user.jsp |

· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术