笔记六中实现了三种过滤器:字符编码过滤、登录权限过滤、敏感词过滤,可是有个缺陷就是,限定了过滤顺序,而不能实现先进行request过滤。最后response过滤,而且中间几项过滤的顺序不能动态改变。所以这里做个改进。实现一个过滤顺序的FilterChain。

多个Filter的运行顺序在这篇博文中得到非常细致的解说,总结一点。多个过滤器的运行顺序是依据web.xml中不同<filter-mapping>的顺序来先后运行的,比方:

<?xml version="1.0" encoding="UTF-8"?

> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>firstFilter</filter-name> <filter-class>com.test.filter.FirstFilter</filter-class> </filter> <filter> <filter-name>secondFilter</filter-name> <filter-class>com.test.filter.SecondFilter</filter-class> </filter> <filter-mapping> <filter-name>secondFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>firstFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>firstServlet</servlet-name> <servlet-class>com.alimama.servlet.FirstServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>firstServlet</servlet-name> <url-pattern>/firstServlet</url-pattern> </servlet-mapping> </web-app>

将会先运行secondFilter,再运行firstFilter。

以下是截取的一段实现Filter接口的doFilter代码,用户自己定义的Filter都实现了这个接口:

 public void doFilter(ServletRequest request, ServletResponse response,   FilterChain chain) throws IOException, ServletException {   System.out.println("before invoke secondFilter's chain.doFilter() ..");   chain.doFilter(request, response);   System.out.println("after invoke secondFilter's chain.doFilter() ..");   }   

能够看到第四行的chain.doFilter(request,response);这句代码是Servlet里的Filter技术的核心,它的主要职能是将请求传递给下一个Filter。

不是一下子所有初始化所有的Filter对象。

根据这个思想,我自定义了一个FilterChain来实现多个过滤器的过滤顺序。

//FilterChain.java
package lewa;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class FilterChain {//private static final String[] filters={"LoginFilter","WordFilter"};private static final Filter[] filters={new LoginFilter(),new WordFilter()};private static int count=0;public void doFilter(ServletRequest request,ServletResponse response,FilterChain fc) throws InstantiationException, IllegalAccessException, Exception{if(count<filters.length){ //Class<Filter> cls=(Class<Filter>)Class.forName(filters[count]);//cls.doFilter(request, response);filters[count++].doFilter(request, response, fc);}}
}

静态成员变量filters里的过滤器实例的顺序能够自行定义,以后想更改过滤顺序仅仅要改这个String数组就能够。

对应的其它Filter也做了更改:

//Filter.java
package lewa;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public interface Filter {public void init();public void doFilter(ServletRequest reuqest,ServletResponse response,FilterChain fc)throws Exception;public void destroy();
}
//EncodingFilter.java
package lewa;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class EncodingFilter implements Filter{@Overridepublic void init() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)throws InstantiationException, IllegalAccessException, Exception{// TODO Auto-generated method stubreuqest.setCharacterEncoding("UTF-8");fc.doFilter(reuqest, response,fc);response.setContentType("text/html;charset=UTF-8");}@Overridepublic void destroy() {// TODO Auto-generated method stub      }}
//LoginFilter.java
package lewa;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;public class LoginFilter implements Filter{public LoginFilter(){}@Overridepublic void init() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)throws  Exception {// TODO Auto-generated method stubHttpServletRequest req=(HttpServletRequest)reuqest;HttpServletResponse resp=(HttpServletResponse)response;HttpSession session=req.getSession();if(session.getAttribute("username")==null){resp.sendRedirect("login.html");}else{fc.doFilter(reuqest, response,fc);//这里必须有一个else,不能直接是运行下一个Filter,由于假设未登陆。
那么敏感词过滤就不必再做,并且能够尝试不加else,你会发现。未登陆前留言会跳转到登陆界面。登陆之后再回到留言界面。
这时候count已经不满足count<filters.length,所以此时敏感词过滤将不会运行。 }}@Overridepublic void destroy() {// TODO Auto-generated method stub}}
//WordFilter.java
package lewa;import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public class WordFilter implements Filter{private static Pattern pattern=null;public static String str=null;private void loadKeyWordProperties(){StringBuffer patternBuffer = new StringBuffer();try{InputStream in =WordFilter.class.getClassLoader().getResourceAsStream("words.properties");Properties properties = new Properties();properties.load(in);Enumeration<?> enu=properties.propertyNames();while(enu.hasMoreElements()){patternBuffer.append((String)enu.nextElement()+"|");}patternBuffer.deleteCharAt(patternBuffer.length()-1);pattern = Pattern.compile(new String(patternBuffer.toString().getBytes("ISO-8859-1"),"UTF-8"));}catch(IOException e){e.printStackTrace();}}@Overridepublic void init() {// TODO Auto-generated method stub}@Overridepublic void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)throws InstantiationException, IllegalAccessException, Exception {// TODO Auto-generated method stub     loadKeyWordProperties();str=reuqest.getParameter("liuyan");try{Matcher m=pattern.matcher(str);str=m.replaceAll("**");}catch(Exception e){e.printStackTrace();}       fc.doFilter(reuqest, response,fc);}@Overridepublic void destroy() {// TODO Auto-generated method stub}
}

最后Servlet里的代码更改:

package lewa;import java.io.IOException;
import java.io.PrintWriter;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;/*** Servlet implementation class Summary*/
public class Summary extends HttpServlet {private static final long serialVersionUID = 1L;/*** @see HttpServlet#HttpServlet()*/public Summary() {super();// TODO Auto-generated constructor stub}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stub}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubFilter filter=new EncodingFilter();FilterChain  fc=new FilterChain();try {filter.doFilter(request, response,fc);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}PrintWriter out=response.getWriter();HttpSession session=request.getSession();String name=(String) session.getAttribute("username");if(name!=null&&!"".equals(name)) {name=new String(name.getBytes("ISO-8859-1"),"UTF-8");}out.println("<html><head><title>留言板内容</title></head><body>");out.println("用户名:"+name);out.println("<br/>"+WordFilter.str+"</body></html>");        }
}

自己定义过滤器链的编写这个是源代码的下载地址。

希望大家多多不吝赐教~~

转载于:https://www.cnblogs.com/gccbuaa/p/6704586.html

Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain...相关推荐

  1. Servlet学习笔记 Servlet原理

    Servlet学习笔记 Servlet原理 一.Servlet基础 1.Servlet执行过程 用户请求一个Servlet,Servlet容器自动构建请求和响应对象,然后执行Servlet的servi ...

  2. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  3. 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码

    吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...

  4. ROS学习笔记七:使用rqt_console和roslaunch

    ROS学习笔记七:使用rqt_console和roslaunch 本节主要介绍在调试时使用的rqt_console和rqt_logger_level,以及一次性打开多个节点的工具roslaunch. ...

  5. 【K210】K210学习笔记七——使用K210拍摄照片并在MaixHub上进行训练

    [K210]K210学习笔记七--使用K210拍摄照片并在MaixHub上进行训练 前言 K210准备工作 K210如何拍摄照片 准备工作 拍摄相关代码定义 用K210拍摄到的照片在MaixHub平台 ...

  6. STM32学习笔记(七)---SysTick

    STM32学习笔记(七)-SysTick 文章目录 STM32学习笔记(七)---SysTick 一.SysTick简介 二.SysTick功能框图 三.SysTick寄存器 四.SYSTICK使用 ...

  7. Polyworks脚本开发学习笔记(七)-完成一个自动化任务

    Polyworks脚本开发学习笔记(七)-完成一个自动化任务 利用之前的命令建立一个自动化脚本 第一步: 设置环境参数 设置注释字体避免出现不兼容中文的乱码,常用微软雅黑 #设置注释字体 VIEW A ...

  8. websocket 获取连接id_Swoole学习笔记七:搭建WebSocket长连接 之 使用 USER_ID 作为身份凭证...

    Swoole学习笔记七:搭建WebSocket长连接 之 使用 USER_ID 作为身份凭证 2年前 阅读 3678 评论 0 喜欢 0 ### 0.前言 前面基本的WebSocket操作,我们基本都 ...

  9. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

最新文章

  1. mxOutlookBarPro中,button是通过for语句动态生成的,如何取得当前单击button的标题呢?...
  2. 高性能js之js文件的加载与解析
  3. 使用SSH执行远程登录
  4. airpods_如何通过AirPods与其他人共享音乐
  5. 【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理
  6. selenium java1.7_selenium-java(第一篇)
  7. 如何解决“本地编辑,更新时传入删除”消息
  8. ubuntu linux桌面快捷方式,Ubuntu下生成桌面快捷方式
  9. BFS java实现,java实现dfs及bfs算法
  10. HTTP 权威指南 阅读笔记
  11. 入职培训分享——第二篇 知识产权篇
  12. js 实现图片放大镜原理
  13. 写好一份数据分析报告需要注意的13个要点
  14. HDU - 1431 素数回文 [ 学到了 ]
  15. 无线服务器网速加快,无线路由器网速慢怎么办?
  16. Py西游攻关之Django(一)
  17. 前端 - 博客系统(页面设计)
  18. 星速配资:煤炭概念股大幅拉升 看好投资机会
  19. docker基础用法及镜像和容器的常用命令大全
  20. 【docker专栏5】详解docker镜像管理命令

热门文章

  1. 解决gnome3 不能设置无线网络属性
  2. 伪mac android,Mac,android sdk,monkey压力测试,真机
  3. P1525关押罪犯(并查集补集)
  4. ksql 数量大于2_别人1加1大于2大于3,雍禾植发1加1小于2……
  5. html编写组织结构,编写模块化的CSS:CSS文件组织结构
  6. angular点击按钮弹出页面_Axure RP8:如何做出点击按钮切换页面效果?
  7. 一张图看懂数据库十年大格局!
  8. java mysql 占位符_在Java中编写带占位符的SQL语句
  9. python format 槽中槽_printf中的槽和实参--对比python struct包
  10. 苹果手机java_iphone手机,苹果手机如何登陆网易163邮箱