zoukankan      html  css  js  c++  java
  • JavaWeb_初识过滤器Filter

      

      菜鸟教程  传送门

      

      过滤器Filter::JavaWeb三大组件之一,它与Servlet很相似,过滤器是用来拦截请求的,而不是处理请求的

      当用户请求某个Servlet时,会先执行部署在这个请求上的Filter,如果Filter“放行”,那么会继承执行用户请求的Servlet;如果Filter不“放行”,那么就不会执行用户请求的Servlet。

    过滤器Filter生命周期

    package com.Gary.filter;
    
    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;
    
    
    @WebFilter("/*")
    public class GaryFilter implements Filter {
    
        public GaryFilter() {
           System.out.println("过滤器-构造方法");
        }
    
        public void destroy() {
            System.out.println("过滤器-destroy()");
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            chain.doFilter(request, response);
            System.out.println("过滤器-doFilter()");
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
            System.out.println("过滤器-init()");
        }
    
    }
    GaryFilter.java

      init(FilterConfig):在服务器启动时会创建Filter实例,并且每个类型的Filter只创建一个实例,从此不再创建!在创建完Filter实例后,会马上调用init()方法完成初始化工作,这个方法只会被执行一次;

       doFilter(ServletRequest req,ServletResponse res,FilterChain chain):这个方法会在用户每次访问“目标资源(<url->pattern>index.jsp</url-pattern>)”时执行,如果需要“放行”,那么需要调用FilterChain的doFilter(ServletRequest,ServletResponse)方法,如果不调用FilterChain的doFilter()方法,那么目标资源将无法执行;

      destroy():服务器会在创建Filter对象之后,把Filter放到缓存中一直使用,通常不会销毁它。一般会在服务器关闭时销毁Filter对象,在销毁Filter对象之前,服务器会调用Filter对象的destory()方法。

      @WebFilter("/*")表示过滤全部的请求

      @WebFilter("/login.jsp")表示过滤登录的请求

      每发起一个请求过滤器都会调用一次doFilter()【通常都是对请求进行过滤,对请求过滤放到chain.doFilter(request, response)上边】

        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            System.out.println("过滤器-请求前");
            chain.doFilter(request, response);
            System.out.println("过滤器-请求后");
        }

      当过滤登录请求时可先指定路径@WebFilter("/login.jsp*")后,修改doFilter()方法,用户访问login.jsp时页面重定向到index.jsp

        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            chain.doFilter(request, response);
            //当访问login.jsp时页面请求重定向
            ((HttpServletResponse)response).sendRedirect("index.jsp");
        }

      通过Web.xml中配置

    <!--   注册    告诉web有哪些filter并告诉其路径 -->
      <filter>
          <filter-name>xxx</filter-name>
          <filter-class>com.Gary.filter.GaryFilter</filter-class>
      </filter>
      
    <!--   filter映射 -->
      <filter-mapping>
          <filter-name>xxx</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
    <filter>指定一个过滤器。
    <filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
    <filter-class>元素用于指定过滤器的完整的限定类名。
    <init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。
    在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
    <filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
    <filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
    <url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
    <servlet-name>指定过滤器所拦截的Servlet名称。
    <dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher>子元素用来指定 Filter 对资源的多种调用方式进行拦截。
    <dispatcher>子元素可以设置的值及其意义
    REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
    INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
    FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
    ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
    web.xml配置各节点说明

    过滤器的应用场景:

      (一)执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作;

      (二)通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用;

      (三)在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理;

      (一)【静态】当编码通过静态设置时可直接放到过滤器doFilter()中

    //    HttpServletRequest ServletRequest
    //    HttpServletRequest ServletResponse
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //对编码进行过滤    类型为ServletResponse
            request.setCharacterEncoding("utf-8");
            chain.doFilter(request, response);
        }

      (一)【动态】当编码通过动态设置时需放到Web.xml中

    <!--   注册    告诉web有哪些filter并告诉其路径 -->
      <filter>
          <filter-name>xxx</filter-name>
          <filter-class>com.Gary.filter.EncodeFilter</filter-class>
     <init-param>
         <param-name>Encoding</param-name>
         <param-value>UTF-8</param-value>
     </init-param>
     </filter>
     
     
    <!--   filter映射 -->
      <filter-mapping>
          <filter-name>xxx</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>

      (一)过滤器中init()初始化编码类型

        private String encoding;
        
        public void init(FilterConfig fConfig) throws ServletException {
            encoding = fConfig.getInitParameter("Encoding");
        }

      (二)doFilter()中设置权限管理过滤  完整项目代码

      Web,xml中配置过滤器映射

      <filter>
        <filter-name>AdminFilter</filter-name>
        <filter-class>com.Gary.filter.AdminFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>AdminFilter</filter-name>
    <!--     访问admin目录下文件做权限过滤 -->
        <url-pattern>/admin/*</url-pattern>
      </filter-mapping>

      实现过滤器中的doFilter,isAdmin对用户是否是管理员进行判断,管理员返回值为True

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    
            HttpServletRequest httpReq = (HttpServletRequest)request;
            HttpServletResponse httpResp = (HttpServletResponse) response;
            Object o = httpReq.getSession().getAttribute("user");
            if(o==null) {
                httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
            }else {
                User u = (User)o;
                if(u.isAdmin()) {
    //                对权限进行放行
                    chain.doFilter(request, response);
                }else {
    //                重定向回首页
                    httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
                }
            }
        }
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <display-name>Gary04</display-name>
      <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
      </welcome-file-list>
      <filter>
        <filter-name>AdminFilter</filter-name>
        <filter-class>com.Gary.filter.AdminFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>AdminFilter</filter-name>
    <!--     访问admin目录下文件做权限过滤 -->
        <url-pattern>/admin/*</url-pattern>
      </filter-mapping>
    </web-app>
    web.xml
    package com.Gary.filter;
    
    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.Gary.model.User;
    
    
    //@WebFilter("/AdminFilter")
    public class AdminFilter implements Filter {
    
     
        public AdminFilter() {
            // 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 httpReq = (HttpServletRequest)request;
            HttpServletResponse httpResp = (HttpServletResponse) response;
            Object o = httpReq.getSession().getAttribute("user");
            if(o==null) {
                httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
            }else {
                User u = (User)o;
                if(u.isAdmin()) {
    //                对权限进行放行
                    chain.doFilter(request, response);
                }else {
    //                重定向回首页
                    httpResp.sendRedirect(httpReq.getContextPath()+"/index.jsp");
                }
            }
        }
    
        /**
         * @see Filter#init(FilterConfig)
         */
        public void init(FilterConfig fConfig) throws ServletException {
            // TODO Auto-generated method stub
        }
    
    }
    AdminFilter.java

    总结

    Filter的三个方法

      void init(FilterConfig):在Tomcat启动时被调用;

      void destroy():在Tomcat关闭时被调用;

      void doFilter(ServletRequest,ServletResponse,FilterChain):每次有请求时都调用该方法;

    FilterConfig类:与ServletConfig相似,用来获取Filter的初始化参数

      ServletContext getServletContext():获取ServletContext的方法;

      String getFilterName():获取Filter的配置名称;

      String getInitParameter(String name):获取Filter的初始化配置,与<init-param>元素对应;

      Enumeration getInitParameterNames():获取所有初始化参数的名称。

    FilterChain类

      void doFilter(ServletRequest,ServletResponse):放行!表示执行下一个过滤器,或者执行目标资源。可以在调用FilterChain的doFilter()方法的前后添加语句,在FilterChain的doFilter()方法之前的语句会在目标资源执行之前执行,在FilterChain的doFilter()方法之后的语句会在目标资源执行之后执行

    各拦截方式:REQUEST、FORWARD、INCLUDE、ERROR,默认是REQUEST方式

      REQUEST:拦截直接请求方式

      FORWARD:拦截请求转发方式

      INCLUDE:拦截请求包含方式

      ERROR:拦截错误转发方式

      <filter>
        <filter-name>DispatcherFilter</filter-name>
        <filter-class>com.Gary.filter.DispatcherFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>DispatcherFilter</filter-name>
        <url-pattern>/dispatcher1.jsp</url-pattern>
        <dispatcher>REQUEST</dispatcher>
      </filter-mapping>
    (如需转载学习,请标明出处)
  • 相关阅读:
    WebApi之DOM的基本介绍
    Javascript常见数据类型API
    JavaScript作用域与对象
    Javascript数组与函数初识
    久等了,你要的 Python 书籍推荐,来了
    六种酷炫Python运行进度条
    python获取系统内存占用信息的实例方法
    在图像中隐藏数据:用 Python 来实现图像隐写术
    付费?是不可能的!20行Python代码实现一款永久免费PDF编辑工具
    Python数据分析实战:使用pyecharts进行数据可视化
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/10319058.html
Copyright © 2011-2022 走看看