ToB企服应用市场:ToB评测及商务社交产业平台

标题: day27-过滤器Filter02 [打印本页]

作者: 篮之新喜    时间: 2022-11-30 00:37
标题: day27-过滤器Filter02
Filter过滤器02

5.Filter过滤器生命周期


6.FilterConfig

6.1FilterConfig基本使用

FilterConfig的简单使用:
DemoFilterConfig:
  1. package com.filter;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. import java.util.Enumeration;
  5. /**
  6. * 演示FilterConfig使用
  7. */
  8. public class DemoFilterConfig implements Filter {
  9.     @Override
  10.     public void init(FilterConfig filterConfig) throws ServletException {
  11.         System.out.println("DemoFilterConfig init方法被调用...");
  12.         //演示通过FilterConfig获取相关的参数
  13.         //获取filter在xml中配置的名字<filter-name>
  14.         String filterName = filterConfig.getFilterName();
  15.         //获取指定参数
  16.         String ip = filterConfig.getInitParameter("ip");
  17.         //filterConfig可以获取到ServletContext,
  18.         // 这意味着filter过滤器可以和任何Servlet进行通信
  19.         ServletContext servletContext = filterConfig.getServletContext();
  20.         //这里可以获取该filter所有的配置的参数名
  21.         // (也可以进一步使用getInitParameter获取指定参数)
  22.         Enumeration<String> initParameterNames =
  23.                 filterConfig.getInitParameterNames();
  24.         //遍历枚举
  25.         while (initParameterNames.hasMoreElements()) {
  26.             System.out.println("名字= " + initParameterNames.nextElement());
  27.         }
  28.         System.out.println("filterName= " + filterName);
  29.         System.out.println("ip= " + ip);
  30.         System.out.println("servletContext= " + servletContext);
  31.     }
  32.     @Override
  33.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
  34.                          FilterChain filterChain) throws IOException, ServletException {
  35.     }
  36.     @Override
  37.     public void destroy() {
  38.     }
  39. }
复制代码
在web.xml文件中配置filter:
  1. <filter>
  2.     <filter-name>DemoFilterConfig</filter-name>
  3.     <filter-class>com.filter.DemoFilterConfig</filter-class>
  4.    
  5.     <init-param>
  6.         <param-name>ip</param-name>
  7.         <param-value>166.66.66.66</param-value>
  8.     </init-param>
  9.     <init-param>
  10.         <param-name>port</param-name>
  11.         <param-value>8888</param-value>
  12.     </init-param>
  13.     <init-param>
  14.         <param-name>email</param-name>
  15.         <param-value>jack@qq.com</param-value>
  16.     </init-param>
  17.    
  18. </filter>
  19. <filter-mapping>
  20.     <filter-name>DemoFilterConfig</filter-name>
  21.     <url-pattern>/abc/*</url-pattern>
  22. </filter-mapping>
复制代码
redeployTomcat,后台输出如下:
可以看到FilterConfig对象可以获取filter过滤器的配置内容。
6.2简单应用-封杀ip

需求:只要某个网段(如以127.0开头的ip)访问我们的web应用,就将其返回登录页面,不允许访问网站。
思路:在web.xml文件中,将要封杀的网段作为初始配置信息。filter实例创建的时候,在init方法中读取配置的要封杀的网段信息,在filter使用的过程中,如果发现用户的请求ip包含了配置的ip网段,就认为是被封杀的ip,进行处理。
细节补充:filter配置的初始化信息只能在init方法中通过FilterConfig对象来获取。为了让doFilter方法中也能使用到,我们在filter类中创建一个属性,在init方法中将获取的配置ip赋给属性,让其在doFilter方法中也能使用。
例子
DemoFilterConfig:
  1. package com.filter;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. import java.util.Enumeration;
  5. /**
  6. * 演示FilterConfig使用
  7. */
  8. public class DemoFilterConfig implements Filter {
  9.     private String ip;//从配置中获取的ip
  10.     @Override
  11.     public void init(FilterConfig filterConfig) throws ServletException {
  12.         System.out.println("DemoFilterConfig init方法被调用...");
  13.         //获取指定参数
  14.         ip = filterConfig.getInitParameter("ip");
  15.     }
  16.     @Override
  17.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
  18.                          FilterChain filterChain) throws IOException, ServletException {
  19.         //通过forbidden ip来控制
  20.         //先获取访问ip
  21.         String remoteAddr = servletRequest.getRemoteAddr();
  22.         if (remoteAddr.contains(ip)) {//如果访问ip包含了配置ip
  23.             //封杀该网段
  24.             System.out.println("当前访问的ip为" + remoteAddr + "-封杀该网段...");
  25.             servletRequest.getRequestDispatcher("/login.jsp")
  26.                     .forward(servletRequest, servletResponse);
  27.             return;//直接返回
  28.         }
  29.         //否则就继续访问目标资源
  30.         filterChain.doFilter(servletRequest, servletResponse);
  31.     }
  32.     @Override
  33.     public void destroy() {
  34.     }
  35. }
复制代码
在web.xml中配置filter:
  1. <filter>
  2.     <filter-name>DemoFilterConfig</filter-name>
  3.     <filter-class>com.filter.DemoFilterConfig</filter-class>
  4.    
  5.     <init-param>
  6.         <param-name>ip</param-name>
  7.         <param-value>127.0</param-value>
  8.     </init-param>
  9.    
  10. </filter>
  11. <filter-mapping>
  12.     <filter-name>DemoFilterConfig</filter-name>
  13.     <url-pattern>/abc/*</url-pattern>
  14. </filter-mapping>
复制代码
redeployTomcat,在浏览器直接访问web应用abc目录下的资源,以触发filter。
可以看到浏览器直接返回登录页面。因为当前访问的ip为127.0.0.1,filter检测到当前地址为封杀网段,将页面直接转发回登录页面。
后台输出:
7.FilterChain过滤器链

一句话FilterChain:在处理某些复杂业务时,一个过滤器不够,可以设计多个过滤器共同完成过滤任务,形成过滤器链。
7.1基本原理示意图

如上,服务器接收请求,将请求中的url和过滤器的配置的url-pattern匹配,如果匹配成功,就会触发过滤器。如果匹配多个过滤器的url-pattern,则执行多个过滤器。
这个返回调用的机制在事务提交上很有用
7.2过滤器链实例演示

需求:演示过滤器链的使用
AFilter:
  1. package com.filter;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. public class AFilter implements Filter {
  5.     @Override
  6.     public void init(FilterConfig filterConfig) throws ServletException {
  7.     }
  8.     @Override
  9.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  10.         System.out.println("AFilter doFilter 的前置代码... ");
  11.         System.out.println("执行AFilter filterChain.doFilter()...");
  12.         filterChain.doFilter(servletRequest, servletResponse);
  13.         System.out.println("AFilter doFilter 的后置代码... ");
  14.     }
  15.     @Override
  16.     public void destroy() {
  17.     }
  18. }
复制代码
BFilter:
  1. package com.filter;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. public class BFilter implements Filter {
  5.     @Override
  6.     public void init(FilterConfig filterConfig) throws ServletException {
  7.     }
  8.     @Override
  9.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  10.         System.out.println("BFilter doFilter 的前置代码... ");
  11.         System.out.println("执行BFilter filterChain.doFilter()...");
  12.         filterChain.doFilter(servletRequest, servletResponse);
  13.         System.out.println("BFilter doFilter 的后置代码... ");
  14.     }
  15.     @Override
  16.     public void destroy() {
  17.     }
  18. }
复制代码
在admin目录下的hi.jsp:
  1. <%--
  2.   Created by IntelliJ IDEA.
  3.   User: li
  4.   Date: 2022/11/29
  5.   Time: 17:55
  6.   Version: 1.0
  7. --%>
  8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  9. <html>
  10. <head>
  11.     <title>admin 目录下的 hi.jsp</title>
  12. </head>
  13. <body>
  14. <h1>admin 目录下的 hi.jsp</h1>
  15. <h1>后台管理</h1>
  16. <a target="_blank" href="https://www.cnblogs.com/#">用户列表</a>||<a target="_blank" href="https://www.cnblogs.com/#">添加用户</a>||<a target="_blank" href="https://www.cnblogs.com/#">删除用户</a>
  17. <hr/>
  18. </body>
  19. </html>
复制代码
在web.xml中配置filter:
  1. <filter>
  2.     <filter-name>AFilter</filter-name>
  3.     <filter-class>com.filter.AFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6.     <filter-name>AFilter</filter-name>
  7.     <url-pattern>/admin/*</url-pattern>
  8. </filter-mapping>
  9. <filter>
  10.     <filter-name>BFilter</filter-name>
  11.     <filter-class>com.filter.BFilter</filter-class>
  12. </filter>
  13. <filter-mapping>
  14.     <filter-name>BFilter</filter-name>
  15.     <url-pattern>/admin/*</url-pattern>
  16. </filter-mapping>
复制代码
redeployTomcat,在浏览器访问http://localhost:8080/filter/admin/hi.jsp。
后台输出如下:
7.3FilterChain注意事项和细节

8.Filter练习

需求:使用过滤器,完成如下要求

练习
topic.jsp:
  1. <%--
  2.   Created by IntelliJ IDEA.
  3.   User: li
  4.   Date: 2022/11/29
  5.   Time: 22:17
  6.   Version: 1.0
  7. --%>
  8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  9. <html>
  10. <head>
  11.     <title>topic</title>
  12. </head>
  13. <body>
  14. <form action="<%=request.getContextPath()%>/hw/showTopic.jsp" method="post">
  15.     <h1>发表对阿凡达电影的评论</h1>
  16.     过滤词:苹果,香蕉
  17.     ${notice}
  18.     用户:<input type="text" name="username"/><br/>
  19.     评论:<textarea cols="15" rows="5" name="topic"></textarea><br/>
  20.     <input type="submit" value="发表评论">
  21. </form>
  22. </body>
  23. </html>
复制代码
showTopic.jsp:
  1. <%--
  2.   Created by IntelliJ IDEA.
  3.   User: li
  4.   Date: 2022/11/29
  5.   Time: 22:18
  6.   Version: 1.0
  7. --%>
  8. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  9. <html>
  10. <head>
  11.     <title>Title</title>
  12. </head>
  13. <body>
  14. <h3>用户:
  15.     <%=request.getParameter("username")%></h3>
  16. <h3>发表的评论是:<%=request.getParameter("topic")%>
  17. </h3>
  18. </body>
  19. </html>
复制代码
TopicFilter:
  1. package com.filter.hw;
  2. import javax.servlet.*;
  3. import java.io.IOException;
  4. public class TopicFilter implements Filter {
  5.     private String[] forbiddenWords;
  6.     @Override
  7.     public void init(FilterConfig filterConfig) throws ServletException {
  8.         //获取配置信息(禁用词)
  9.         String forbiddenWord = filterConfig.getInitParameter("forbiddenWord");
  10.         forbiddenWords = forbiddenWord.split(",");
  11.     }
  12.     @Override
  13.     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
  14.                          FilterChain filterChain) throws IOException, ServletException {
  15.         //注意中文乱码问题!!!
  16.         servletRequest.setCharacterEncoding("utf-8");
  17.         //获取用户评论
  18.         String username = servletRequest.getParameter("username");
  19.         String topic = servletRequest.getParameter("topic");
  20.         //评论不能为空
  21.         if (topic == null || "".equals(topic)) {
  22.             servletRequest.setAttribute("notice", "评论不能为空!");
  23.             servletRequest.getRequestDispatcher("/hw/topic.jsp")
  24.                     .forward(servletRequest, servletResponse);
  25.             return;
  26.         }
  27.         //判断评论是否有禁用词
  28.         for (String forbiddenWord : forbiddenWords) {
  29.             if (topic.contains(forbiddenWord)) {
  30.                 servletRequest.setAttribute("notice", "含有敏感词...");
  31.                 servletRequest.getRequestDispatcher("/hw/topic.jsp")
  32.                         .forward(servletRequest, servletResponse);
  33.                 return;
  34.             }
  35.         }
  36.         //如果没有禁用词,且评论不为空
  37.         servletRequest.getRequestDispatcher("/hw/showTopic.jsp")
  38.                 .forward(servletRequest, servletResponse);
  39.     }
  40.     @Override
  41.     public void destroy() {
  42.     }
  43. }
复制代码
在web.xml中配置filter:
  1. <filter>
  2.     <filter-name>TopicFilter</filter-name>
  3.     <filter-class>com.filter.hw.TopicFilter</filter-class>
  4.    
  5.     <init-param>
  6.         <param-name>forbiddenWord</param-name>
  7.         <param-value>香蕉,苹果</param-value>
  8.     </init-param>
  9. </filter>
  10. <filter-mapping>
  11.     <filter-name>TopicFilter</filter-name>
  12.    
  13.     <url-pattern>/hw/showTopic.jsp</url-pattern>
  14. </filter-mapping>
复制代码
redeployTomcat,在浏览器访问http://localhost:8080/filter/hw/topic.jsp

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4