zoukankan      html  css  js  c++  java
  • 过滤器

    过滤器定义:

    Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

    它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

    Filter功能

    在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。
    在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据

    过滤器的开发流程

    1  配置web.xml

    <filter>
        <filter-name>characterFileter</filter-name>
        <filter-class>com.rl.characterfilter.CharacterFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>characterFileter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
      <filter>
        <filter-name>loginFilter</filter-name>
        <filter-class>com.rl.loginfilter.LoginFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>loginFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
      </filter-mapping>
    

      2  实现Filter接口

    package com.rl.characterfilter;
    
    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.rl.utils.MyRequest;
    
    
    public class CharacterFilter implements Filter {
    
        /**
         * Default constructor. 
         */
        public CharacterFilter() {
            // TODO Auto-generated constructor stub
        }
    
    	
    	public void destroy() {
    		// TODO Auto-generated method stub
    	}
    
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    		
    		//转换请求
    		
    		HttpServletRequest servletRequest=(HttpServletRequest) request;
    		HttpServletResponse servletResponse=(HttpServletResponse) response;
    		//处理响应乱码
    		servletResponse.setContentType("text/html;charset=utf-8");
    		//创建增强对象   要增强原来的request对象,必须先获取到原来的request对象
    		MyRequest myRequest=new MyRequest(servletRequest);
    		//放行的时候应该传入增强后的request对象    myRequest
    		chain.doFilter(myRequest, servletResponse);
    	}
    
    	
    	public void init(FilterConfig fConfig) throws ServletException {
    		// TODO Auto-generated method stub
    	}
    
    }
    

      在上面的代码中创建MyRequest  类 去增强request    为其编码。(装饰者模式)

      装饰模式定义:装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。
    它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

    MyRequest    设计:(要增强原来的request  故继承HttpServletRequestWrapper  重写getParameterMap()方法  为了契合开发时使用getParameter()方法获取参数是为其编码  我对这个方法也做了重写)

    package com.rl.utils;
    
    import java.io.UnsupportedEncodingException;
    import java.lang.reflect.Method;
    import java.util.Map;
    import java.util.Set;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    public class MyRequest extends HttpServletRequestWrapper{
    	/* 第一步:总结:继承HttpServletRequestWrapper,为了偷懒,
         *         不用自己去实现所有HttpServletRequest的方法 
         * 第二步:使用构造函数将原来的request对象保存到当前自定义对象中
         * 第三步:针对要修改的方法,进行增强 
         * 第四步:定义一个flag标记,防止编码重复执行
         * */
    
    
    	// 定义了一个成员变量,用来保存构造函数传入的requset对象
        private HttpServletRequest request = null;
     
        // 定义一个标记,用来标注:当前requset中,请求参数,是否已经编码过了
        private boolean flag = false;
    	public MyRequest(HttpServletRequest request) {
    		super(request);
    		this.request=request;
    		// TODO Auto-generated constructor stub
    	}
    	// 总需求:对request对象的获取数据的方法,进行增强(统一编码)
    	
    	  @Override
    	public java.util.Map<String, String[]> getParameterMap() {
    		//获得请求方法  post/  get
    		String method=request.getMethod();
    		if("post".equalsIgnoreCase(method)){
    			try {
    			
    				request.setCharacterEncoding("utf-8");
    			} catch (UnsupportedEncodingException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			java.util.Map<String, String[]> map=request.getParameterMap();
    			return map;
    		}/*如果是get方式*/
    		else if("get".equalsIgnoreCase(method)){
    			 Map<String, String[]> map = this.request.getParameterMap();
    			 /*如果已经编码了 直接返回map*/
    			 if(flag){
    				 return map;
    			 }
    			 else{
    				 if(map==null){
    					 return super.getParameterMap();//?
    				 }else{
    				 //获取参数名集合
    					 Set<String> keys=map.keySet();
    					 //遍历每一个参数  为其值编码
    					 for(String key:keys){
    						 //考虑到一个个名字有多个值(复选框,下拉列表框等)  故用一个数组来存放值
    						 String [] values=map.get(key);
    						 //对每一个值进行编码
    						 for(int i=0;i<values.length;i++){
    							 try {
    								values[i]=new String(values[i].getBytes("utf-8"), "utf-8");
    								System.out.println(values[i]+"values[i]");
    							} catch (UnsupportedEncodingException e) {
    								// TODO Auto-generated catch block
    								e.printStackTrace();
    							}
    						 }
    						 
    					 }
    				 }
    				 //编码完成后  设置flag=true
    				 flag=true;
    			 }
    		}
    		else{
    			 //位置请求方式,自定义对象处理不了,使用父类的方法处理
    			  return super.getParameterMap();
    		}
    		return super.getParameterMap();
    		
    	}
    	
    	@Override
    	public String getParameter(String name) {
    		boolean flag=false;
    		String method=request.getMethod();
    		if(flag){
    			return super.getParameter(name);
    		}
    		else{
    			if("post".equalsIgnoreCase(method)){
    				try {
    					request.setCharacterEncoding("utf-8");
    				} catch (UnsupportedEncodingException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				
    			}else if("get".equalsIgnoreCase(method)){
    				String param=request.getParameter(name);
    				try {
    					param=new String(param.getBytes("utf-8"), "utf-8");
    				} catch (UnsupportedEncodingException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				return param;
    			}else{
    				return super.getParameter(name);
    			}
    		}
    		
    		// TODO Auto-generated method stub
    	   return super.getParameter(name);
    	}
    
    }
    

      上面是对字符编码的过滤器的实现 

      接下来我对登录做了一个过滤器 如下:

    package com.rl.loginfilter;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    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() {
            // TODO Auto-generated constructor stub
        }
    
    	public void destroy() {
    		// TODO Auto-generated method stub
    	}
    
    	
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    		// 获得在下面代码中要用的request,response,session对象  
            HttpServletRequest servletRequest = (HttpServletRequest) request;  
            HttpServletResponse servletResponse = (HttpServletResponse) response;  
            HttpSession session = servletRequest.getSession();  
            /*contextPath /Filter*/
    		String contextpath=request.getServletContext().getContextPath();
    		
    		/* uri/Filter/login.jsp*/
    		String uri=servletRequest.getRequestURI();
    		/* url  http://localhost:8080/Filter/login.jsp*/
    		StringBuffer url=servletRequest.getRequestURL();
    		//如果是登录页面放行
    		if(uri.indexOf("/login.jsp")>-1){
    			chain.doFilter(request, response);
    		}else{
    			/*取用户的session值*/
    			String user=(String) session.getAttribute("user");
    			if("".equals(user)||user==null){
    				servletResponse.sendRedirect("/Filter/login.jsp");
    			}
    			else{
    				chain.doFilter(request, response);
    			}
    		}
    	
    	
    		
    	}
    
    	public void init(FilterConfig fConfig) throws ServletException {
    		// TODO Auto-generated method stub
    	}
    
    }
    

      

  • 相关阅读:
    springboot + rabbitmq 做智能家居,我也没想到会这么简单
    分享 10个我常逛的国外技术社区,真的受益匪浅!
    被迫重构代码,这次我干掉了 if-else
    过滤器 和 拦截器 6个区别,别再傻傻分不清了
    看了 100多份简历后,想给找工作的程序员几点建议
    不会看 Explain执行计划,劝你简历别写熟悉 SQL优化
    友情链接
    关于我
    10w行级别数据的Excel导入优化记录
    kafka 监控工具 eagle 的安装(内附高速下载地址)
  • 原文地址:https://www.cnblogs.com/MyJavaStudy/p/9289960.html
Copyright © 2011-2022 走看看