20.【filter过滤器】

什么是过滤器

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。

实现第一个Filter程序

创建MyServlet

@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out=response.getWriter();
        out.print("Hello MyServlet ");

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doPost(request,response);
    }
}

创建MyFilter

用配置文件(web.xml)实现filter

1.先创建一个Filter类,该类要实现Filter接口
在idea中,点右键,新建Filter,输入文件名MyFilter1
在这里插入图片描述

MyFilter1:

public class MyFilter1 implements Filter {
    public void destroy() {
        //过滤器对象在销毁时自动调用,释放资源
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用

        PrintWriter out=resp.getWriter();

        out.write("HelloMyFilter");
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        //过滤器对象在初始化时调用,可以配置一些初始化参数
    }

}

web.xml

<filter>
        <filter-name>MyFilter1</filter-name>
        <filter-class>filter.MyFilter1</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFilter1</filter-name>
        <url-pattern>/MyServlet</url-pattern>
    </filter-mapping>

<filter>根元素用于注册一个Filter

<filter-name>子元素用于设置Filter名称

<filter-class>子元素用于设置Filter类的完整名称

<filter-mapping>根元素用于设置一个过滤器所拦截的资源

<filter-name>子元素必须 与中的子元素相同。

<url-pattern>子元素用于匹配用户请求的URL.例如”/MyServlet”,这个URL还可以使用通配符””来表示,例如:“.do”适用于所有 以”.do” 结尾的Servlet路径。
运行http://localhost:8080/MyServlet
结果:HelloMyFilterHello MyServlet

用注解实现filter
@WebFilter("/MyServlet")
public class MyFilter2 implements Filter {
    public void destroy() {
        //过滤器对象在销毁时自动调用,释放资源
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用

        PrintWriter out=resp.getWriter();

        out.write("HelloMyFilter");
        chain.doFilter(req, resp);
    
    }

    public void init(FilterConfig config) throws ServletException {
        //过滤器对象在初始化时调用,可以配置一些初始化参数

    }

}

Filter映射

使用通配符“*”拦截用户的所有请求

<url-pattern>子元素用于匹配用户请求的URL.例如”/MyServlet”,这个URL还可以使用通配符””来表示,例如:“.do”适用于所有 以”.do” 结尾的Servlet路径。在注解中修改

@WebFilter("*.do")
public class MyFilter2 implements Filter {
    public void destroy() {
        //过滤器对象在销毁时自动调用,释放资源
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        //用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用

        PrintWriter out=resp.getWriter();

        out.write("HelloMyFilter2");
      //  chain.doFilter(req, resp); 

    }

    public void init(FilterConfig config) throws ServletException {
        //过滤器对象在初始化时调用,可以配置一些初始化参数

    }

}

Filter链

在一个Web应用程序中可以注册多个Filter程序,每个Filter程序都可以针对某一个URL进行拦截。如果多个Filter程序都对同一个URL进行拦截,那么这些Filter就会组成一个Filter链(也叫过滤器链)。Filter链用FilterChain对象来表示,FilterChain对象中有一个doFilter()方法,该方法的作用就是让Filter链上的当前过滤器允许,请求进入下一个Filter。
MyFilter01.java

public void doFilter(ServletRequest request,ServletResponse response, FilterChain chain) throws IOException, ServletException {

        //用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用

        PrintWriterout=response.getWriter();

        out.write("HelloMyFilter01<br/>");

        chain.doFilter(request,response);

    }

MyFilter02.java

 public void doFilter(ServletRequest request,ServletResponse response, FilterChain chain) throws IOException, ServletException {

        //用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用

        PrintWriterout=response.getWriter();

        out.write("MyFilter02 Before<br/>");

        chain.doFilter(request,response);

        out.write("MyFilter02 After<br/>");

    }

Web.xml

<filter>

    <display-name>MyFilter01</display-name>

    <filter-name>MyFilter01</filter-name>

    <filter-class>cn.lctvu.filter.MyFilter01</filter-class>

 </filter>

 <filter-mapping>

    <filter-name>MyFilter01</filter-name>

    <url-pattern>/MyServlet</url-pattern>

 </filter-mapping>

 <filter>

    <display-name>MyFilter02</display-name>

    <filter-name>MyFilter02</filter-name>

    <filter-class>cn.lctvu.filter.MyFilter02</filter-class>

 </filter>

 <filter-mapping>

    <filter-name>MyFilter02</filter-name>

    <url-pattern>/MyServlet</url-pattern>

  </filter-mapping>

注意:Filter链中各个Filter的拦截顺序与它们在Web.xml文件中元素的映射顺序一致,由于MyFilter01的元素位于MyFilter02的元素前面,因此用户的访问请求首先会被MyFilter01拦截,然后再被MyFilter02拦截。

在3.0之后新增@WebFilter注解,当使用注解配置多个Filter时,用户无法控制其执行顺序,此时Filter过滤的顺序是按照Filter的类名来控制的,按自然排序的规则。

FilterConfig接口

为了获取Filter程序在web.xml文件中的配置信息,Servlet API提供了一个FilterConfig接口,该接口封装了Filter程序在web.xml中的所有注册信息,并且提供了一系列获取这些配置信息的方法。
MyFilter03

public class MyFilter03 implements Filter {
    private String characterEncoding;

    FilterConfig fc;
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        // 输出参数信息

        characterEncoding=fc.getInitParameter("encoding");

        System.out.println("encoding初始化参数值:"+characterEncoding);
        chain.doFilter(req, resp);
    }

    public void init(FilterConfig config) throws ServletException {
        this.fc=config;

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

聊城云在天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值