java servlet中的Filter

Filter也成为过滤器,Java web开发人员通过Filter对浏览器向web服务器请求进行拦截,比如jsp请求,servlet,html请求等,然后

实现一些特殊的功能,如实现url级别的访问控制,过滤敏感信息,压缩响应信息等一系列功能。

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:

 Filter的拦截原理:Filter中有一个我们编写好Filter,并配置好对哪一个资源进行拦截后WEb服务器每次调用serivce方法的时候都会先调用Filter的doFilter对访问进行拦截,因此使用Filter重点是重写它的doFilter方法:

  1. 调用目标资源之前,让一段代码执行。
  2. 是否调用目标资源(即是否让用户访问web资源)。
  3. 调用目标资源之后,让一段代码执行。

  web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对 象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方 法,即web资源就会被访问,否则web资源不会被访问。

Filter开发步骤

  Filter开发分为二个步骤:

  1. 编写java类实现Filter接口,并实现其doFilter方法。
  2. 在 web.xml 文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。
package springboot.demo;
/**
 * @Auther opprash
 * @Date 2018\8\1 0001 7:05
 */

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class MyFilter implements Filter {
    @Override
    public void destroy() {
        // TODO Auto-generated method stub
    }

    @Override
    public void doFilter(ServletRequest srequest, ServletResponse sresponse, FilterChain filterChain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        // 对request和response进行一些预处理
        srequest.setCharacterEncoding("UTF-8");
        sresponse.setCharacterEncoding("UTF-8");
        sresponse.setContentType("text/html;charset=UTF-8");
        HttpServletRequest request = (HttpServletRequest) srequest;
        System.out.println("this is MyFilter,url :"+request.getRequestURI());
        filterChain.doFilter(srequest, sresponse);//let it do!
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub
    }
}

xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>    
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <!--配置过滤器-->
  <filter>
      <filter-name>MyFilter</filter-name>
      <filter-class>springboot.demo</filter-class>
  </filter>
  
  <!--映射过滤器-->
  <filter-mapping>
      <filter-name>MyFilter</filter-name>
      <!--“/*”表示拦截所有的请求 -->
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  
</web-app>

Filter链

  在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
  web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

Filter的部署

  Filter的部署分为两个步骤:

  1、注册Filter

  2、映射Filter

.注册Filter

  开发好Filter之后,需要在web.xml文件中进行注册,这样才能够被web服务器调用

  在web.xml文件中注册Filter范例:

  <filter>
            <description>MyFilter1过滤器</description>
            <filter-name><yFilter1</filter-name>
            <filter-class>springboot.demo.MyFilter1</filter-class>
            <!--配置FilterDemo02过滤器的初始化参数-->
            <init-param>
                <description>配置MyFilter1过滤器的初始化参数</description>
                <param-name>name</param-name>
                <param-value>springboot</param-value>
           </init-param>
           <init-param>
               <description>配置MyFilter1过滤器的初始化参数</description>
               <param-name>like</param-name>
               <param-value>java</param-value>
           </init-param>
 </filter>

 <description>用于添加描述信息,该元素的内容可为空,<description>可以不配置。

  <filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
  <filter-class>元素用于指定过滤器的完整的限定类名。
  <init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。如果过滤器不需要指定初始化参数,那么<init-param>元素可以不配置。

映射Filter

  在web.xml文件中注册了Filter之后,还要在web.xml文件中映射Filter

  <!--映射过滤器-->
   <filter-mapping>
       <filter-name>MyFilter1</filter-name>
       <!--“/*”表示拦截所有的请求 -->
       <url-pattern>/*</url-pattern>
   </filter-mapping>

  <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 对资源的多种调用方式进行拦截。如下:

 <filter-mapping>
    <filter-name>testFilter</filter-name>
    <url-pattern>/index.jsp</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
 </filter-mapping>

  <dispatcher> 子元素可以设置的值及其意义:

  1. REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
  2. INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
  3. FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
  4. ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

猜你喜欢

转载自blog.csdn.net/qq_30675777/article/details/81284385