zoukankan      html  css  js  c++  java
  • 初学filter

    一. Filter介绍

    Filter可以认为是Servlet的一种加强版,它主要用于对用户请求进行预处理,也可以对HTTPServletResponse进行后处理,是个典型的处理链。它的完整处理流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

    Filter有如下几个用处:

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

    Filter有如下种类

    • 用户授权的Filter:filter负责检查用户请求,根据请求过滤用户非法请求
    • 日志Filter:详细记录某些特殊的用户请求
    • 负责解码的Filter:包括对非标准编码的请求编码。
    • 能改变XML内容的XSLT Filter等
    • Filter可拦截多个请求或响应;一个请求或响应也可被多个Filter拦截

    创建Filter的两个步骤

    • 创建Filter处理类
    • web.xml文件中配置Filter

    二. 创建Filter

    创建Filter必须实现Javax.servlet.Filter接口,在该接口定义了如下三个方法

    • void init():用于Filter的初始化
    • void destroy():用于Filter销毁前,完成某些资源的回收
    • void doFilter():实现过滤功能
    @WebFilter(filterName = "Filter")
    public class Filter implements javax.servlet.Filter {
        private FilterConfig config;
        public void destroy() {
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            ServletContext context = this.config.getServletContext();
            long before = System.currentTimeMillis();
            System.out.println("开始过滤...");
            HttpServletRequest request = (HttpServletRequest)req;
            System.out.println("已经截获到用户的请求地址"+request.getServletPath());
            chain.doFilter(req,resp);
            long after = System.currentTimeMillis();
            System.out.println("过滤结束");
            System.out.println("请求被定位到"+request.getServletPath()+",所花的时间为"+(after-before));
            
        }
    
        public void init(FilterConfig config) throws ServletException {
            this.config = config;
        }
    
    }

    如果时检查权限的filter,则根据用户请求的HttpSession,判断用户权限是否足够。如果权限不够,直接调用重定向即可,无需调用chain.doFilter()方法

    三. 配置Filter

    配置Filter和配置Servlet非常相似,需要配置如下两个部分

    • 配置Filter名
    • 配置FIlter拦截URL模式

    配置Filter同样有两种方式

    • 在Filter类中通过注解进行配置
    • 在web.xml中通过配置文件进行配置

    @webFilter修饰一个Filter类,用于对Filter进行配置,它支持下表的常用属性

     

    @webFilter支持的常用属性
    属性 是否必须 说明
    asyncSupported 指定Filter是否支持异步操作模式
    dispatcherTypes 指定该Filter对哪种dispatcher模式的请求进行过滤,该属性支持ASYNC,FORWARD,INCLUDE,REQUEST这5个值的任意组合
    displayName 指定Filter的显示名
    filterName 指定该Filter的名称
    initParams 用于该FIlter配置参数
    servletNames 该属性可指定多个Servlet的名称,用于指定该Filter仅对这几个Servlet执行过滤
    urlPatterns/value 指定该Filter拦截的URL

    在web.xml中也可以配置Filter,与配置Servlet类似,如下是为上面程序配置的

    <!--定义Filter-->
        <filter>
            <filter-name>log</filter-name>
            <filter-class>java.gdut.filter.Filter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>log</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

    实际上Filter和Servlet十分相似,区别只是Filter的doFilter()方法里多了一个FilterChain的参数,通过该参数可以控制是否放行用户请求。在实际项目中,Filter的doFilter() 方法里的代码就是从多Servlet的Service()方法里抽取的通用代码,通过使用Filter可以实现更好的代码复用。例如权限控制,日志记录等。

    由于Filter与Servlet非常相似,所以它们的生命周期配置初始化参数非常相似。可以参考Servlet 一章(http://www.cnblogs.com/yumiaoxia/p/9032758.html)

      下面将定义一个较为实用的Filter,该Filter对用户请求进行过滤,该Filter通过doFilter()方法来设置request编码的字符集,从而避免每个JSP,servlet                           都需要设置;还会验证用户是否登录,如果没有登录,系统直接跳转到登录页面

    @WebFilter(filterName = "AuthorityFilter",urlPatterns = {"/*"},
            initParams = {@WebInitParam(name="encoding",value = "GBK")
    @WebInitParam(name="loginPage",value = "/login.jsp")
    @WebInitParam(name="prologin",value = "/progin.jsp")})
    public class AuthorityFilter implements Filter {
        private FilterConfig config;
        public void destroy() {
            this.config = null;
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            String encoding = config.getInitParameter("encoding");
            String loginPage = config.getInitParameter("loginPage");
            String proLogin = config.getInitParameter("prologin");
            req.setCharacterEncoding(encoding);
            HttpServletRequest request = (HttpServletRequest) req;
            HttpSession session = request.getSession(true);
            String requestPath = request.getServletPath();
            
            if(session.getAttribute("user") == null 
                    && !requestPath.endsWith(loginPage) 
                    && !requestPath.endsWith(proLogin)){
                request.setAttribute("tip","您还没登录");
                request.getRequestDispatcher("/loginPage").forward(req,resp);
            }else{
                //放行
                chain.doFilter(req,resp);
            }
            
            chain.doFilter(req, resp);
        }
    
        public void init(FilterConfig config) throws ServletException {
            this.config = config;
    
        }
    
    }

    三. 使用URL Rewririte实现网页的伪静态

    对于以JSP为表现层开发的动态网站来说,用户访问URL通常有如下形式:

    xxx.jsp?param=value...

    大部分搜索引擎都会优先考虑收录静态的HTML页面,而不是这种动态的*.jsp、*.php页面。但实际上绝大部分网站都是动态的,不可能全部是静态的HTML页面。因此互联网上大部分网站都会考虑使用——伪静态。就是将*.jsp,*.php这种动态的URL伪装成静态的HTML页面                       

    对于Java Web应用说,要实现伪静态非常简单:可以通过Filter拦截所有发向*.html请求,然后按某种规则将请求forward到实际的*.jsp页面即可。现有的URL Rewrite开源项目为这种思路提供了实现。使用URLRewrite实现网站的伪静态也非常简单。

    1. 登录http://tuckey.org/urlrewrite/站点下载Url Rewrite的最新版本。
    2. 下载URL Rewrite。直接下载它的urlrewritefilter-4.0.3.jar即可,并将该jar包复制到web应用的WEB-INF/lib路径下
    3. 在web.xml文件中配置启用URL Rewrite Filter,在web.xml文件添加如下片段
      <!--配置URL Rewrite的Filter拦截所有的请求-->
          <filter>
              <filter-name>UrlRewriteFilter</filter-name>
              <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
          </filter>
          <filter-mapping>
              <filter-name>UrlRewriteFilter</filter-name>
              <url-pattern>/*</url-pattern>
          </filter-mapping>
    4. 在应用的WEB-INF路径下增加urlrewrite.xml文件,该文件定义了伪静态映射规则,这份规则是基于正则表达式的。

    下面是本应用所使用的urlrewrite.xml伪静态规则文件。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE urlrewrite  PUBLIC "-//tuckey.org//DTD UrlRewrite 4.0//EN">
    <!-- Configuration file for UrlRewriteFilter http://www.tuckey.org/urlrewrite/ -->
    <urlrewrite>
        <rule>
            <!--所有配置如下正则表达式的请求-->
            <from>/userinf-(/w*).html</from>
            <to type="forward">/userinf.jsp?username=$1</to>
        </rule>
    </urlrewrite>

     

     

     

     

  • 相关阅读:
    Spark2.4.5集群安装与本地开发
    Windows玩转Kubernetes系列4-搭建K8S Dashboard
    Windows玩转Kubernetes系列3-Centos安装K8S
    Windows玩转Kubernetes系列2-Centos安装Docker
    Windows玩转Kubernetes系列1-VirtualBox安装Centos
    Lock wait timeout exceeded?代码该优化了
    RocketMQ初入门踩坑记
    Java8虚拟机(JVM)内存溢出实战
    CentOS 7 下 JDK1.8+Maven+Nginx+MySql+Git+Redis环境安装
    消息中间件—SpringBoot下RabbitMQ实战
  • 原文地址:https://www.cnblogs.com/yumiaoxia/p/9036623.html
Copyright © 2011-2022 走看看