Servlet过滤器——Filter

  1. 一、首先来了解一下什么是过滤器:
  • 二、Filter特点:
  • 三、过滤器的实现:
  • 四、对请求信息的过滤:
  • 五、对响应信息的过滤:
  • 前言:
    过滤器是Servlet中一个非常重要的组成部分,进行WEB开发时无不用到过滤器;因此这篇blog来单独总结下关于过滤器的知识点。


    一、首先来了解一下什么是过滤器:

    下面这句话引自这篇文章
      Filte即过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
      Servlet API中提供了一个Filter接口,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下:
      在这里插入图片描述

    二、Filter特点:
    • Servlet过滤器可以检查和修改ServletRequest和ServletResponse对象。
    • Servlet过滤器可以被指定和特定的URL关联,且不能独立执行,只有当客户请求访问该URL时,才会触发过滤器。
    • Servlet过滤器可以被串联在一起,形成管道效应,协同修改请求和响应对象(过滤器链)。
      在这里插入图片描述
      三、过滤器的实现:
      建立一个过滤器涉及下列五个步骤:
    1. 建立一个实现Filter接口的类;
    2. 在doFilter方法中实现过滤行为;
    3. 调用FilterChain对象的doFilter方法;
    4. 对相应的servlet和JSP页面注册过滤器;
    5. 禁用激活器servlet;

    1、建立一个实现Filter接口的类

    • Servlet过滤器类必须实现javax.servlet.Filter
    • 这个接口含有3个过滤器类必须实现的方法:
        init( )
        doFilter( )
        destroy( )
    • public void init(FilterConfig config) thows ServletException只在此过滤器第一次初始化时执行
    • 简单过滤器可提供此方法的空体,两种情况使用init:
    1. FilterConfig对象提供对servlet环境及web.xml文件中指派的过滤器名的访问。利用init将FilterConfig对象存放在一个字段中,以便doFilter方法能够访问servlet环境或过滤器名。
    2. FilterConfig对象具有一个getInitParameter方法,它能够访问部署描述符文件(web.xml)中分配的过滤器初始化参数。

    2、在doFilter方法中实现过滤行为:

    • 重要方法:
         public void doFilter(ServletRequset request, ServletResponse response,FilterChain chain)   

    3、调用FilterChain对象的doFilter方法:

    • 最后一个参数FilterChain对象。对此对象调用以激活与servlet或JSP相关的下一个过滤器。如果没有另一个相关的过滤器,则对doFilter的调用激活servlet或JSP本身

    4、对相应的servlet和JSP页面注册过滤器:

    • web.xml中用于过滤器的元素:
      filter:元素向系统注册一个过滤对象
      filter-mapping:元素指定该过滤对象所应用的URL
      <filter-name>必需元素,必须与用filter元素声明时给予过滤器的名称相匹配
      <url-pattern>必需元素,此元素声明一个以斜杠"/"开始的模式,它指定过滤器应用的URL。

    例:
    要求:利用filter和filter-mapping指示名为SomeFilter的过滤器应用到名为SomeServlet的servlet。

    web.xml应配置为:

    <filter>
       <filter-name>SomeFilter</filter-name>
       <filter-class>sPackage.SFilterClass</filter-class>
    </filter>
    <filter-mapping> 
       <filter-name>SomeFilter</filter-name>
       <servlet-name>SomeServlet</servlet-name>
    </filter-mapping>

    5、禁用激活器servlet:

    • 在对资源应用过滤器时,可通过指定要应用过滤器的URL模式或servlet名来完成。
    • 如果提供servlet名,则此名称必须与web.xml的servlet元素中给出的名称相匹配。
    • 如果使用应用到一个serlvet的URL模式,则此模式必须与利用web.xml的元素servlet-mapping指定的模式相匹配。
    • 防止用户利用缺省servlet URL绕过过滤器设置 。
    四、对请求信息的过滤:

    对请求信息的过滤大致分为下列5个步骤:

    1. Servlet容器创建一个过滤器实例。
    2. 过滤器实例调用init方法,读取过滤器初始化参数。
    3. 过滤器实例调用doFilter方法,根据初始化参数的值判断该请求是否合法。
    4. 如果该请求不合法则阻塞该请求。
    5. 如果该请求合法则调用chain.doFilter方法将该请求向后续传递。

    因为Servlet对中文支持不好,用户提交的表单信息会产生乱码问题,会给后台的数据查询和记录(数据库存储)等功能造成影响,因此需要对请求信息进行转码。

    解决方法一:
    直接在Servlet中转码

    处理get请求::

        String name = request.getParameter(param_name);
        name = new String( name.getBytes("ISO8859_1") );

    处理post请求:

    request.setCharacterEncoding("utf-8");

    直接在servlet里处理的缺点是从request中取出的每个中文变量都要转换,且不能动态的改变编码。

    解决方法二:
    在过滤器中进行转码,且在一个动态web项目里设置完成后就可以不用在单个Servlet中一一设置了。
    例:
    Filter类:

    public class MyFilter  implements Filter
    {  private String tarEncoding = "gb2312";
        protected FilterConfig filterConfig;
        public void init(FilterConfig config) throws ServletException 
        {   this.filterConfig = config;    
            this.tarEncoding =    config.getInitParameter("encoding"); 
         }    
        public void doFilter( ServletRequest srequest, ServletResponse sresponse, FilterChain chain) throws IOException, ServletException 
        {
        HttpServletRequest request =   (HttpServletRequest)srequest;
        HttpServletResponse response = (HttpServletResponse)sresponse;
        //把请求用指定的方式编码     
        request.setCharacterEncoding(targetEncoding);
      //把响应用指定的方式编码
        response.setCharacterEncoding(targetEncoding);
      // 把处理发送到下一个过滤器     
        chain.doFilter(srequest,sresponse); 
        }    
        public void destroy() 
        {    this.filterConfig=null; }     
    }
    

    过滤器部署描述:

    <filter>
        <filter-name>encod</filter-name>
        <filter-class>pdsu.edu.cn.chu.MyFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>gb2312</param-value>
        </init-param>
     </filter>
    <filter-mapping>
         <filter-name>encod</filter-name>
          <url-pattern>/*</url-pattern>
    <filter-mapping>

    过滤器只能解决Post提交的中文乱码问题,Get提交中文乱码解决方法为:

    修改tomcat配置文件下的server.xml,找到对8080端口进行服务的Connector组件的设置部分,为Connector添加属性URIEncoding="GBK"
    在这里插入图片描述

    五、对响应信息的过滤:
    1. 过滤器截获客户端的请求.
    2. 重新封装ServletResponse,在封装后的ServletResponse中提供用户自定义的输出流;即:
      在这里插入图片描述
    3. 将请求向后续传递。
    4. Web组件产生响应。
    5. 从封装后的ServletResponse中获取用户自定义的输出流。
    6. 将响应内容通过用户自定义的输出流写入到缓冲流。
    7. 在缓冲流中修改响应的内容后清空缓冲流,输出响应内容。

    🆗,关于Filter的总结暂时就这么多。 = ̄ω ̄=


    转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2058751973@qq.com

    ×

    喜欢就点赞,疼爱就打赏