zoukankan      html  css  js  c++  java
  • Java Web进阶——Filter过滤器

    一、过滤器的介绍:

    • 在Servlet规范2.3中定义了过滤器,它是一个服务器端的组件,可以截取用户端的请求与响应信息,并且对这些信息进行过滤。
    • Servlet过滤器本身并不生成请求和响应对象,只是提供过滤功能。
    • Servlet过滤器能够在Servlet被调用之前检查Request对象,并修改Request Header和Request内容。
    • Servlet过滤器可以过滤的Web组件包括Servlet,JSP和HTML等文件。

    本文源码——GitHub:

     https://github.com/imperio-wxm/wordpressCode/tree/master/Filter


    二、过滤器在实际开发中的应用场景

    1.对用户请求进行统一认证
    2.编码转换
    3.对用户发送的数据进行过滤替换
    4.转换图像格式
    5.对相应的内容进行压缩

    三、过滤器的工作原理

    【没有过滤器】:

    用户直接访问WEB资源。

    【有过滤器】:

    WEB容器启动时进行过滤器的加载,用户发出请求到过滤器,过滤器判断请求是否符合规则,符合规则的请求通过过滤器发送给WEB资源,WEB资源响应的信息返回给过滤器,过滤器再将WEB资源的响应返回给用户。


    四、过滤器的生命周期(类似Servlet的生命周期)

    1.实例化——通过web.xml进行配置加载,在容器启动时只会实例化一次
    2.初始化——调用init()方法,加载信息只会执行一次
    3.过滤——使用doFilter()方法进行多次过滤
    4.销毁——WEB容器关闭时调用destroy()方法进行销毁

    所有的Servlet过滤器都必须实现javax.servlet.Filter接口,并实现该接口中的三个方法。

    【init()方法】
    • 这是过滤器的初始化方法,web容器创建过滤器实例后将调用这个方法。这个方法中可以web.xml文件中过滤器的参数。
    【doFilter()方法】
    • 这个方法完成实际的过滤操作。这个地方是过滤器的核心方法,当用户请求访问与过滤器关联的URL时,web容器将先调用过滤器的doFilter方法。
    • FilterChain方法参数可以调用chain.doFilter方法,将请求传给下一个过滤器(或目标资源),或利用转发、重定向请求转发到其他资源。
    【destroy()方法】
    • web容器在销毁过滤器实例前调用该方法,在这个方法中可以释放过滤器占用的资源。

    【生命周期代码演示】

    复制代码
    package com.filter;
    
    import javax.servlet.*;
    import java.io.IOException;
    
    /**
     * Created by wxm-Imperio
     */
    public class FirstFilter implements Filter {
       @Override
       public void destroy() {
          System.out.println("destroy,firstFilter");
       }
       @Override
       public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
          throws IOException, ServletException { System.out.println("start,doFilter,firstFilter"); filterChain.doFilter(servletRequest, servletResponse); System.out.println("End,doFilter,firstFilter"); } @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("init。firstFilter"); } }
    复制代码

    【web.xml配置】

    复制代码
    <filter>
         <filter-name>Filter的名字</filter-name>
         <filter-class>Filter类的名字</filter-class>
         <init-param>
         <description>描述信息可以省略或者放在此处</description>
         <param-name>参数名称</param-name>
         <param-value>参数的值</param-value>
         </init-param>
    </filter>
    <filter-mapping>
         <filter-name>Filter的名字</filter-name>
         <url-pattern>URL</url-pattern>
         <dispatcher></dispatcher>//过滤器类型
    </filter-mapping>
    复制代码

    注意:一般Filter配置在所有的Servlet之前。


    五、支持多个过滤器

    • 每个过滤器有不同的URL地址
    • 当不同的过滤器URL地址相同时,会生成过滤器链:
    • 用户请求——依次每个过滤器——web资源(顺序是:服务器按照web.xml中过滤器定义的先后顺序组成一条链)
    【用户请求】——>【过滤器1Chain.doFilter前代码——>过滤器1Chain.doFilter——>过滤器2Chain.doFilter前代码——>过滤器1Chain.doFilter.......】——>【Servlet的Service方法处理请求】——>...........【过滤器2Chain.doFilter后代码——>过滤器1Chain.doFilter后代码】——>【返回用户请求】

    【过滤器链的web.xml配置】

    复制代码
    <!--过滤器1的配置信息--!>
    <filter>
         <filter-name>Filter1的名字</filter-name>
         <filter-class>Filter1类的名字</filter-class>
         <init-param>
         <description>描述信息可以省略或者放在此处</description>
         <param-name>参数名称</param-name>
         <param-value>参数的值</param-value>
         </init-param>
    </filter>
    <filter-mapping>
         <filter-name>Filter1的名字</filter-name>
         <url-pattern>URL</url-pattern>
         <dispatcher></dispatcher>//过滤器类型
    </filter-mapping>
    
    <!--过滤器2的配置信息--!>
    <filter>
         <filter-name>Filter2的名字</filter-name>
         <filter-class>Filter2类的名字</filter-class>
         <init-param>
         <description>描述信息可以省略或者放在此处</description>
         <param-name>参数名称</param-name>
         <param-value>参数的值</param-value>
         </init-param>
    </filter>
    <filter-mapping>
         <filter-name>Filter2的名字</filter-name>
         <url-pattern>URL</url-pattern>
         <dispatcher></dispatcher>//过滤器类型
    </filter-mapping>
    复制代码

    注意:过滤器的执行顺序就是在web.xml里配置的顺序。


    六、过滤器的分类

    Servlet2.5:

    1.REQUEST(默认)用户直接访问页面时,web容器将会调用过滤器。
    2.FORWORD 目标源是通过RequestDispatcher的forword方法访问时,该过滤器被调用。
    3.INCLUDE 目标资源时通过RequestDispatcher的include方法调用时,过滤器被调用。
    4.ERROR 目标资源是通过声明式异常处理机制调用时,过滤器将被调用。
     
    【语法】
    @WebFilter(servletNames = {"SimpleServlet"} filterName = "SimpleFilter")
    
    public class LessThanSixFilter implements Filter {
    //类中内容
    }

    【ERROR的配置信息】

    复制代码
    <error-page>
       <error-code>404</error-code>
       <location>/error.jsp</location>
    </error-page>
    
    <filter>
       <filter-name>errorFilter</filter-name>
       <filter-class>com.filter.ErrorFilter</filter-class>
    </filter>
    <filter-mapping>
       <filter-name>errorFilter</filter-name>
       <url-pattern>/error.jsp</url-pattern>
    </filter-mapping>
    复制代码

    【ErrorFilter过滤器代码】

    复制代码
    public class ErrorFilter implements Filter {
       @Override
       public void destroy() {
       }
       @Override
       public void init(FilterConfig filterConfig) throws ServletException {
       }
       @Override
       public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 
        throws IOException, ServletException { System.out.println("检测到有错误信息"); } }
    复制代码

    Servlet3.0:

    (新增)ASYNC 支持异步处理
    • @WebFilter(引言)用于将一个声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置相应的类部署为过滤器

    【异步操作处理代码:过滤器不等待线程,直接执行后面内容,实现异步处理】

    AsynServlet

    复制代码
    //设置Servlet支持异步
    @WebServlet(name = "AsynServlet", asyncSupported = true)
    public class AsynServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException { System.out.println("Servlet执行开始时间" + new Date()); //实现异步操作 AsyncContext context = request.startAsync(); //开启异步线程 new Thread(new Executor(context)).start(); System.out.println("Servlet执行结束时间" + new Date()); } protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException { doPost(request, response); } //内部类模拟线程 public class Executor implements Runnable { private AsyncContext context; //实现构造方法 public Executor(AsyncContext context) { this.context = context; } @Override public void run() { //执行相关的复杂业务 try { Thread.sleep(1000 * 10); //context.getRequest(); //context.getResponse(); System.out.println("业务执行完成时间" + new Date()); } catch (InterruptedException e) { e.printStackTrace(); } } } }
    复制代码

    AsvnFilter过滤器

    复制代码
    //注解
    @WebFilter(filterName = 
      "AsynFilter", value = {"/AsynServlet"}, asyncSupported = true, dispatcherTypes = {DispatcherType.REQUEST,DispatcherType.ASYNC}) public class AsynFilter implements Filter { @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
         throws IOException, ServletException { System.out.println("Start..........AsynFilter"); filterChain.doFilter(servletRequest, servletResponse); System.out.println("End..........AsynFilter"); } }
    复制代码

    web.xml配置

    复制代码
    <servlet>
       <servlet-name>AsynServlet</servlet-name>
       <servlet-class>com.servlet.AsynServlet</servlet-class>
    </servlet>
    <servlet-mapping>
       <servlet-name>AsynServlet</servlet-name>
       <url-pattern>/AsynServlet</url-pattern>
    </servlet-mapping>
    复制代码

    七、FilterConfig的使用

    Filter的init方法中提供了一个FilterConfig对象,提供相关的操作:

    如获取Filter中配置的初始化参数web.xml配置:

    复制代码
    <filter>
          <filter-name>LoginFilter</filter-name>
          <filter-class>com.itzhai.login.LoginFilter</filter-class>
          <init-param>
              <param-name>username</param-name>
              <param-value>arthinking</param-value>
          </init-param>
    </filter>
    复制代码

    在init()方法中获取:

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //获取Filter初始化参数
        String username = filterConfig.getInitParameter("username");
    }

    在Filter中访问application:

    ServletContext context = filterConfig.getServletContext();

    也可以在doFilter方法中根据转换好的request获取:

    HttpServletRequest req = (HttpServletRequest)request;
    ServletContext context = req.getSession().getServletContext();

    八、项目实例

    慕课网中用户登录的加强版Demo,利用过滤器对用于请求和服务器回应进行过滤。

    GitHub源码:https://github.com/imperio-wxm/projectDemo

  • 相关阅读:
    English,The Da Vinci Code, Chapter 23
    python,meatobject
    English,The Da Vinci Code, Chapter 22
    English,The Da Vinci Code, Chapter 21
    English,The Da Vinci Code, Chapter 20
    English,The Da Vinci Code, Chapter 19
    python,xml,ELement Tree
    English,The Da Vinci Code, Chapter 18
    English,The Da Vinci Code, Chapter 17
    English,The Da Vinci Code, Chapter 16
  • 原文地址:https://www.cnblogs.com/AutumnRhyme/p/4316280.html
Copyright © 2011-2022 走看看