zoukankan      html  css  js  c++  java
  • Web应用中Filter的定义和使用

    web开发中,客户端发来请求时,可以对请求和回应信息进行过滤,或者说对RequestResponse进行拦截。比如对数据编码,加解密,验证用户合法性,过滤垃圾数据等。

     

    定义过滤器类

    必须实现 java.servlet.Filter接口  

    实现三个方法:

    1、init(FilterConfigfilterConfig) 初始化过滤器,在Servlet容器启动时(一般为tomcat启动时)创建Filter实例的时候就会调用该方法,所以如果修改了其中的内容,需要重启tomcat才行。多用于读取web.xml文件中Servlet过滤器的初始化参数。

                                                                            

    2、doFilter(ServletRequest request,ServletResponseresponse,FilterChain chain)  进行过滤处理,所有过滤处理都在这个方法中实现

    处理完毕,需要调用chain.doFilter(request,response)方法,把请求继续向后传递,可以是对下一个过滤器doFilter方法的调用,或者相应的web组件。所以Filter采用了职责链设计模式。

    然后继续在这等着其他请求,类似于Servletservice()

     

    3、destroy() 过滤器销毁  Servlet容器在销毁过滤器实例之前该方法得到调用,以释放占用的资源。

     

    设置字符集

    response

    页面中文显示:

    <%@ page language="java"contentType="text/html; charset=GB18030"

     

    使用PrintWriter输出中文

    response.setContentType("text/xml;charset=utf-8");

     

    request

    否则,每个Servlet或者JSP都需要设置request字符集,例如

    // 设置request字符集(文件头设置response字符集)

             request.setCharacterEncoding("GB18030");

     

    原理图


     

    CharsetEncodingFilter.java

     

    public class CharsetEncodingFilter implements Filter {
     
     //设置默认的字符集,避免忘了配置Filter文件设置字符集导致出现乱码
    private String encoding = "UTF-8";
     
    @Override
    public void doFilter(ServletRequest request, ServletResponseresponse,
    FilterChain chain) throws IOException, ServletException {
     
    // 设置字符集
    //                request.setCharacterEncoding("GBK");
    request.setCharacterEncoding(encoding);
     
    // 继续执行
    chain.doFilter(request, response);
    }
     
    @Override
    public void init(FilterConfig filterConfig) throwsServletException {
    //从配置文件中CharsetEncodingFilter的init-param中取值,如果没有的话就使用默认的
    encoding = filterConfig.getInitParameter("encoding");
    }
     
    @Override
    public void destroy() {
     
    }
    }


     

    web.xml

     

    <filter>
    <filter-name>CharsetEncodingFilter</filter-name>
    <filter-class>com.java.drp.util.filter.CharsetEncodingFilter</filter-class>
    <init-param>
    <param-name>encoding</param-name>
    <param-value>GBK</param-value>
    </init-param>
    </filter>
    <filter-mapping>
    <filter-name>CharsetEncodingFilter</filter-name>
    <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>CharsetEncodingFilter</filter-name>
    <url-pattern>/servlet/*</url-pattern>
    </filter-mapping>

     


    防止url跳转,判断用户是否已登录

    AuthFilter.java

     

    		public class AuthFilter implements Filter {
    		
    			@Override
    			public void destroy() {
    			}
    		
    			@Override
    			public void doFilter(ServletRequest request, ServletResponse response,
    					FilterChain chain) throws IOException, ServletException {
    				
    				HttpServletRequest req = (HttpServletRequest)request;
    				HttpServletResponse resp = (HttpServletResponse)response;
    				
    				// /DRP6.3/login.jsp
    				String reqURI = req.getRequestURI();
    				// 截取字符串,得到/login.jsp
    				String subReqURI = reqURI.substring(reqURI.indexOf("/", 1), reqURI.length());
    				
    				// 如果是登陆页或者验证码的servlet,继续执行;否则进行验证
    				if (!"/login.jsp".equals(subReqURI) && !"/servlet/util/AuthImageServlet".equals(subReqURI)) {
    					// 如果用户没有登录,则跳到登陆页
    					HttpSession session = req.getSession(false);
    					if (session == null || session.getAttribute("user_info") == null) {
    						resp.sendRedirect(req.getContextPath() + "/login.jsp");
    						return;
    					}
    				}
    				// 继续执行
    				chain.doFilter(request, response);
    			}
    		
    			@Override
    			public void init(FilterConfig arg0) throws ServletException {
    				
    			}
    		
    		}


    web.xml

     

    		<filter>
    			<filter-name>AuthFilter</filter-name>
    			<filter-class>com.java.drp.util.filter.AuthFilter</filter-class>
    		</filter>
    		<filter-mapping>
    			<filter-name>AuthFilter</filter-name>
    			<url-pattern>*.jsp</url-pattern>
    		</filter-mapping>
    		<filter-mapping>
    			<filter-name>AuthFilter</filter-name>
    			<url-pattern>/servlet/*</url-pattern>
    		</filter-mapping>
    


    //改善登陆页:当session过期,子页面跳出框架,变成登陆页

    if(window.self != window.top){

    //用当前窗口位置引用覆盖顶层窗口位置引用,使得没有父亲引用

    window.top.location = window.self.location;

    }

     

    Web Cache

    对于在一定时间内不变的图片或者js文件等,无需每次请求都重新加载,而是放在缓存中。

    还可以使用第三方产品 OSCache

     

    WebCacheFilter.java

     

    publicclass WebCacheFilter implements Filter {
     
    @Override
    publicvoid destroy() {
     
    }
     
    @Override
    publicvoid doFilter(ServletRequest req, ServletResponse resp,
    FilterChainchain) throws IOException, ServletException {
     
    HttpServletRequestrequest = (HttpServletRequest)req;
    HttpServletResponseresponse = (HttpServletResponse)resp;
     
    //设置Cache-control
    response.setHeader("Cache-control","max-age=5000");
    //继续执行
    chain.doFilter(request,response);
    }
     
    @Override
    publicvoid init(FilterConfig arg0) throws ServletException {
     
    }
    }



    web.xml

     

    <filter>
    <filter-name>WebCacheFilter</filter-name>
    <filter-class>com.java.drp.util.filter.WebCacheFilter</filter-class>
    </filter>
    <filter-mapping>
    <filter-name>WebCacheFilter</filter-name>
    <url-pattern>*.gif</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>WebCacheFilter</filter-name>
    <url-pattern>*.jpg</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>WebCacheFilter</filter-name>
    <url-pattern>*.png</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>WebCacheFilter</filter-name>
    <url-pattern>*.js</url-pattern>
    </filter-mapping>
    <filter-mapping>
    <filter-name>WebCacheFilter</filter-name>
    <url-pattern>*.css</url-pattern>
    </filter-mapping>



    分析特点

    • 只对post请求起作用,而页面默认是get请求,所以想通过filter需要显示声明method
    • 责任链,多个filter,后进先出
    • 生命周期类似servlet,只实例化一次,然后等待。
    • AOPAspect-Oriented Programming)面向切面编程,是一种横切性的技术
    • 提供一种声明式服务,具有可插拔能力。

     

  • 相关阅读:
    CAS实战の简介
    高效程序员的45个习惯の排除万难奋勇前进
    高效程序员的45个习惯の对事不对人
    高效程序员的45个习惯の欲速则不达
    高效程序员的45个习惯の正确做事
    Java中Runnable和Thread的区别
    Intellij IDEA 14的注册机(Java版)
    session token防表单重提
    maven下@override标签失效
    Oracle sql 优化の索引监控
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3069802.html
Copyright © 2011-2022 走看看