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

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

  1. <?xml version="1.0" encoding="UTF-8"?
  2.  
  3. >
  4. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  7. http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  8. <welcome-file-list>
  9. <welcome-file>index.jsp</welcome-file>
  10. </welcome-file-list>
  11. <filter>
  12. <filter-name>firstFilter</filter-name>
  13. <filter-class>com.test.filter.FirstFilter</filter-class>
  14. </filter>
  15. <filter>
  16. <filter-name>secondFilter</filter-name>
  17. <filter-class>com.test.filter.SecondFilter</filter-class>
  18. </filter>
  19. <filter-mapping>
  20. <filter-name>secondFilter</filter-name>
  21. <url-pattern>/*</url-pattern>
  22. </filter-mapping>
  23. <filter-mapping>
  24. <filter-name>firstFilter</filter-name>
  25. <url-pattern>/*</url-pattern>
  26. </filter-mapping>
  27.  
  28. <servlet>
  29. <servlet-name>firstServlet</servlet-name>
  30. <servlet-class>com.alimama.servlet.FirstServlet</servlet-class>
  31. </servlet>
  32. <servlet-mapping>
  33. <servlet-name>firstServlet</servlet-name>
  34. <url-pattern>/firstServlet</url-pattern>
  35. </servlet-mapping>
  36. </web-app>

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

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

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

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

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

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

  1. //FilterChain.java
  2. package lewa;
  3.  
  4. import javax.servlet.ServletRequest;
  5. import javax.servlet.ServletResponse;
  6.  
  7. public class FilterChain {
  8. //private static final String[] filters={"LoginFilter","WordFilter"};
  9. private static final Filter[] filters={new LoginFilter(),new WordFilter()};
  10. private static int count=0;
  11. public void doFilter(ServletRequest request,ServletResponse response,FilterChain fc) throws InstantiationException, IllegalAccessException, Exception{
  12. if(count<filters.length){
  13. //Class<Filter> cls=(Class<Filter>)Class.forName(filters[count]);
  14. //cls.doFilter(request, response);
  15. filters[count++].doFilter(request, response, fc);
  16. }
  17. }
  18. }

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

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

  1. //Filter.java
  2. package lewa;
  3.  
  4. import javax.servlet.ServletRequest;
  5. import javax.servlet.ServletResponse;
  6.  
  7. public interface Filter {
  8. public void init();
  9. public void doFilter(ServletRequest reuqest,ServletResponse response,FilterChain fc)throws Exception;
  10. public void destroy();
  11. }
  1. //EncodingFilter.java
  2. package lewa;
  3.  
  4. import java.io.IOException;
  5.  
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9.  
  10. public class EncodingFilter implements Filter{
  11.  
  12. @Override
  13. public void init() {
  14. // TODO Auto-generated method stub
  15.  
  16. }
  17.  
  18. @Override
  19. public void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)throws InstantiationException, IllegalAccessException, Exception{
  20. // TODO Auto-generated method stub
  21. reuqest.setCharacterEncoding("UTF-8");
  22. fc.doFilter(reuqest, response,fc);
  23. response.setContentType("text/html;charset=UTF-8");
  24. }
  25.  
  26. @Override
  27. public void destroy() {
  28. // TODO Auto-generated method stub
  29. }
  30.  
  31. }
  1. //LoginFilter.java
  2. package lewa;
  3.  
  4. import javax.servlet.ServletRequest;
  5. import javax.servlet.ServletResponse;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import javax.servlet.http.HttpSession;
  9.  
  10. public class LoginFilter implements Filter{
  11. public LoginFilter(){}
  12.  
  13. @Override
  14. public void init() {
  15. // TODO Auto-generated method stub
  16.  
  17. }
  18.  
  19. @Override
  20. public void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)
  21. throws Exception {
  22. // TODO Auto-generated method stub
  23. HttpServletRequest req=(HttpServletRequest)reuqest;
  24. HttpServletResponse resp=(HttpServletResponse)response;
  25. HttpSession session=req.getSession();
  26. if(session.getAttribute("username")==null){
  27. resp.sendRedirect("login.html");
  28. }else{
  29. fc.doFilter(reuqest, response,fc);//这里必须有一个else,不能直接是运行下一个Filter,由于假设未登陆。
  30. 那么敏感词过滤就不必再做,并且能够尝试不加else,你会发现。未登陆前留言会跳转到登陆界面。登陆之后再回到留言界面。
  31. 这时候count已经不满足count<filters.length,所以此时敏感词过滤将不会运行。
  32. }
  33. }
  34.  
  35. @Override
  36. public void destroy() {
  37. // TODO Auto-generated method stub
  38.  
  39. }
  40.  
  41. }
  1. //WordFilter.java
  2. package lewa;
  3.  
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.util.Enumeration;
  7. import java.util.Properties;
  8. import java.util.regex.Matcher;
  9. import java.util.regex.Pattern;
  10.  
  11. import javax.servlet.ServletRequest;
  12. import javax.servlet.ServletResponse;
  13.  
  14. public class WordFilter implements Filter{
  15.  
  16. private static Pattern pattern=null;
  17. public static String str=null;
  18.  
  19. private void loadKeyWordProperties(){
  20. StringBuffer patternBuffer = new StringBuffer();
  21. try{
  22. InputStream in =WordFilter.class.getClassLoader().getResourceAsStream("words.properties");
  23. Properties properties = new Properties();
  24. properties.load(in);
  25. Enumeration<?> enu=properties.propertyNames();
  26. while(enu.hasMoreElements()){
  27. patternBuffer.append((String)enu.nextElement()+"|");
  28. }
  29. patternBuffer.deleteCharAt(patternBuffer.length()-1);
  30. pattern = Pattern.compile(new String(patternBuffer.toString().getBytes("ISO-8859-1"),"UTF-8"));
  31. }catch(IOException e){
  32. e.printStackTrace();
  33. }
  34. }
  35. @Override
  36. public void init() {
  37. // TODO Auto-generated method stub
  38.  
  39. }
  40.  
  41. @Override
  42. public void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)
  43. throws InstantiationException, IllegalAccessException, Exception {
  44. // TODO Auto-generated method stub
  45. loadKeyWordProperties();
  46. str=reuqest.getParameter("liuyan");
  47. try{
  48. Matcher m=pattern.matcher(str);
  49. str=m.replaceAll("**");
  50. }catch(Exception e){
  51. e.printStackTrace();
  52. }
  53. fc.doFilter(reuqest, response,fc);
  54. }
  55.  
  56. @Override
  57. public void destroy() {
  58. // TODO Auto-generated method stub
  59.  
  60. }
  61. }

最后Servlet里的代码更改:

  1. package lewa;
  2.  
  3. import java.io.IOException;
  4. import java.io.PrintWriter;
  5.  
  6. import javax.servlet.ServletException;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. import javax.servlet.http.HttpSession;
  11.  
  12. /**
  13. * Servlet implementation class Summary
  14. */
  15. public class Summary extends HttpServlet {
  16. private static final long serialVersionUID = 1L;
  17.  
  18. /**
  19. * @see HttpServlet#HttpServlet()
  20. */
  21. public Summary() {
  22. super();
  23. // TODO Auto-generated constructor stub
  24. }
  25.  
  26. /**
  27. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  28. */
  29. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  30. // TODO Auto-generated method stub
  31. }
  32.  
  33. /**
  34. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  35. */
  36. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  37. // TODO Auto-generated method stub
  38. Filter filter=new EncodingFilter();
  39. FilterChain fc=new FilterChain();
  40. try {
  41. filter.doFilter(request, response,fc);
  42. } catch (Exception e) {
  43. // TODO Auto-generated catch block
  44. e.printStackTrace();
  45. }
  46. PrintWriter out=response.getWriter();
  47. HttpSession session=request.getSession();
  48. String name=(String) session.getAttribute("username");
  49. if(name!=null&&!"".equals(name)) {
  50. name=new String(name.getBytes("ISO-8859-1"),"UTF-8");
  51. }
  52. out.println("<html><head><title>留言板内容</title></head><body>");
  53. out.println("用户名:"+name);
  54. out.println("<br/>"+WordFilter.str+"</body></html>");
  55. }
  56. }

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

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

Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain的更多相关文章

  1. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  2. Typescript 学习笔记七:泛型

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

  3. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  4. 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整

    今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...

  5. # jsp及servlet学习笔记

    目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...

  6. Servlet学习笔记(四)

    目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...

  7. Servlet学习笔记(三)

    目录 Servlet学习笔记(三) 一.HTTP协议 1.请求:客户端发送欸服务器端的数据 2.响应:服务器端发送给客户端的数据 3.响应状态码 二.Response对象 1.Response设置响应 ...

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

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

  9. python3.4学习笔记(七) 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

随机推荐

  1. Java并发(十七):ConcurrentHashMap

    先做总结: 1.HashMap HashTable ConcurrentHashMap HashMap:线程不安全 HashTable:线程安全,每个方法都加了 synchronized 修饰.类似 ...

  2. 对于asp.net mvc异步查询

    如何做MVC异步查询,做列表页面. 查询是项目中必不可少的工作,而且不同的项目不同的团队,都有自己的简单方法.Asp.net mvc 有自己独特的优势,下面是结合mvc实现一个产品列表的Demo. 问 ...

  3. 华为S5300系列升级固件S5300SI-V100R006C00SPC800.cc

    这个固件附带了web,V100R005可以直接升级到这个版本,但没什么必要,因为V100R005本身可以直接升级到V200. 升级小插曲: 1.升级的使用使用Windows,不要用Mac或者Linux ...

  4. saga中的saga(A Saga on Sagas)

    此文翻译自msdn,侵删. 原文地址:https://msdn.microsoft.com/en-us/library/jj591569.aspx Process Managers, Coordina ...

  5. 2007 Audi A4 INSTRUMENT CLUSTER WIRING DIAGRAM

    BOSCH RB8 8E0920 951G I found the answer by myself...... Here is what it's work for me. GREEN CONNEC ...

  6. MAX II Device Compatibility with 5.0-V CMOS Devices

    http://www.altera.com/literature/hb/max2/max2_mii51009.pdf The open-drain pin never drives high, onl ...

  7. C语言每日小练(四)——勇者斗恶龙

    勇者斗恶龙 你的王国里有一条n个头的恶龙,你希望雇佣一些骑士把它杀死(砍掉全部的头). 村里有m个骑士能够雇佣.一个能力值为x的骑士能够砍掉恶龙一个致敬不超过x的头,且须要支付x个金币. 怎样雇佣骑士 ...

  8. android studio 引用aar

    在:libs拷贝对应的文件 build.gradle repositories {    flatDir {        dirs 'libs'    }}dependencies {   // c ...

  9. 学习笔记:AC自动机

    话说AC自动机有什么用......我想要自动AC机 AC自动机简介:  首先简要介绍一下AC自动机:Aho-Corasick automation,该算法在1975年产生于贝尔实验室,是著名的多模匹配 ...

  10. 【ContestHunter】【弱省胡策】【Round5】

    反演+FFT+构造+DP 写了这么多tag,其实我一个也不会 A 第一题是反演……数据范围10W,看着就有种要用FFT等神奇算法的感觉……然而蒟蒻并不会推公式,只好写了20+10分的暴力,然而特判30 ...