zoukankan      html  css  js  c++  java
  • Servlet学习笔记(七)—— 自己定义过滤器的编写改进:自己定义实现FilterChain

          笔记六中实现了三种过滤器:字符编码过滤、登录权限过滤、敏感词过滤,可是有个缺陷就是,限定了过滤顺序,而不能实现先进行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{
    
    	@Override
    	public void init() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)throws InstantiationException, IllegalAccessException, Exception{
    		// TODO Auto-generated method stub
    		reuqest.setCharacterEncoding("UTF-8");
    		fc.doFilter(reuqest, response,fc);
    		response.setContentType("text/html;charset=UTF-8");
    	}
    
    	@Override
    	public 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(){}
    
    	@Override
    	public void init() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public void doFilter(ServletRequest reuqest, ServletResponse response,FilterChain fc)
    			throws  Exception {
    		// TODO Auto-generated method stub
    		HttpServletRequest 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,所以此时敏感词过滤将不会运行。 
                    }
    	}
    
    	@Override
    	public 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();
    		}
    	}
    	@Override
    	public void init() {
    		// TODO Auto-generated method stub
    		
    	}
    
    	@Override
    	public 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);
    	}
    
    	@Override
    	public 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 stub
    		Filter filter=new EncodingFilter();
    		FilterChain  fc=new FilterChain();
    		try {
    			filter.doFilter(request, response,fc);
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.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>");		
    	}
    }
     

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

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



  • 相关阅读:
    ACMICPC 2009 China Northeast Area Contest :(
    2576 数论
    sql source control and sql prompt
    C语言中的单精度双精度数的有效位数
    [软件调试学习笔记]防止栈缓冲区溢出的基于Cookie的安全检查机制
    A tiny introduction to asynchronous IO
    Mysql扩展之replication概述
    C语言中的单精度双精度数的有效位数
    MySQL Cluster(MySQL 集群) 初试
    MySQL Cluster(MySQL 集群) 初试
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6704586.html
Copyright © 2011-2022 走看看