Filter过滤器

Javaweb中的过滤器可以拦截所有访问web资源的请求或响应操作。

原理图


Filter快速入门

步骤:

  • 创建一个类实现Filter接口
  • 重写接口中方法 doFilter方法是真正过滤的。
  • 在web.xml文件中配置

注意:在Filter的doFilter方法内如果没有执行chain.doFilter(request,response)
那么资源是不会被访问到的。

1、创建一个类实现Filter接口

package com.yanglin.filter;

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

public class Myfilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("在启动服务器的时候就创建");
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("拦截");
        //放行,执行完相应的操作之后会返回来的
        filterChain.doFilter(servletRequest,servletResponse);

        System.out.println("返回");
    }
    @Override
    public void destroy() {
        System.out.println("销毁");
    }
}

2、在web.xml文件中配置

<!--配置拦截-->
<filter>
    <filter-name>Myfilter</filter-name>
    <filter-class>com.yanglin.filter.Myfilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Myfilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

FilterChain

FilterChain 是 servlet 容器为开发人员提供的对象,它提供了对某一资源的已过滤请求调用链的视图。过滤器使用 FilterChain 调用链中的下一个过滤器,如果调用的过滤器是链中的最后一个过滤器,则调用链末尾的资源。

怎样可以形成一个Filter链?
只要多个Filter对同一个资源进行拦截就可以形成Filter链

怎样确定Filter的执行顺序?
由的先后顺序来确定
如下先执行MyFilter2,在再执行MyFilter

<filter-mapping>
    <filter-name>MyFilter2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping> -->
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Filter生命周期:
Filter生命周期与servlet什么周期很像都是:实例化 –> 初始化 –> 服务 –> 销毁

  • 当服务器启动,会创建Filter对象,并调用init方法,只调用一次.
  • 当访问资源时,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,这个方法是真正拦截操作的方法.
  • 当服务器关闭时,会调用Filter的destroy方法来进行销毁操作.

FilterConfig:
在Filter的init方法上有一个参数,类型就是FilterConfig.
FilterConfig它是Filter的配置对象,它可以完成下列功能

1.获取Filter名称
2.获取Filter初始化参数
3.获取ServletContext对象。

这里写图片描述

在Filter中获取一个FIlterConfig对象

public class Myfilter implements Filter {
    private FilterConfig config;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
        System.out.println("在启动服务器的时候就创建");
    }
}

Filter配置:
基本配置如上所述

<filter>
    <filter-name>filter名称</filter-name>
    <filter-class>Filter类的包名.类名</filter-class>
</filter>
<filter-mapping>
    <filter-name>filter名称</filter-name>
    <url-pattern>路径</url-pattern>
</filter-mapping>

1、< url-pattern>
完全匹配 以”/demo1”开始,不包含通配符*
目录匹配 以”/”开始 以*结束
扩展名匹配 .xxx 不能写成/.xxx

2、< servlet-name>:它是对指定的servlet名称的servlet进行拦截的。

3、< dispatcher>:可以取的值有 REQUEST FORWARD ERROR INCLUDE
作用是:当以什么方式去访问web资源时,进行拦截操作.

  • REQUEST 当是从浏览器直接访问资源,或是重定向到某个资源时进行拦截方式配置的 它也是默认值
  • FORWARD 它描述的是请求转发的拦截方式配置
  • ERROR 如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
  • NCLUDE 如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用
<filter-mapping>
    <filter-name>MyFilter3</filter-name>
    <url-pattern>/*</url-pattern>
    <!--拦截所有的include和request请求-->
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping> 

案例:创建一个get,post编码过滤器

使用适配器模式,重写HttpServletRequest

package com.yanglin.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

/**
 * Created by yanglin on 2016/10/31.
 */
public class Globalfilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

    }

    @Override
    public void destroy() {

    }
}

class MyRequest extends HttpServletRequestWrapper{
    private HttpServletRequest hsr ;

    boolean flg = true;

    public MyRequest(HttpServletRequest request) {
        super(request);
        this.hsr = request;
    }

    @Override
    public String getParameter(String name) {
        Map<String, String[]> map = this.getParameterMap();
        return map.get(name)[0];
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        Map<String, String[]> map = hsr.getParameterMap();// 乱码
        if(flg){
            for (Map.Entry<String, String[]> m : map.entrySet()) {
                String[] values = m.getValue();
                for (int i = 0; i < values.length; i++) {
                    try {
                        values[i] = new String(
                                values[i].getBytes("iso-8859-1"), "UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }

            }
            flg = false;
        }
        return map;
    }

    @Override
    public String[] getParameterValues(String name) {
        Map<String, String[]> map = getParameterMap();
        return map.get(name);
    }
}

web.xml注册为所有的请求都需要过滤

<!--配置拦截-->
<filter>
    <filter-name>Myfilter</filter-name>
    <filter-class>com.yanglin.filter.Globalfilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>Myfilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值