【Filter】java EE web三大核心之-Filter全面解析

一、什么是过滤器

过滤器是介于客户端与服务器目标资源之间的一道过滤技术。对访问请求进行过滤,过滤器可以先行一步对请求进行预处理。比如判断用户是否登录,是否具备访问权限等。最重要的是,一个过滤器可以拦截一个或多个访问请求进行过滤,一个请求也可以被多个过滤器过滤。如果为一个请求配置了多个过滤器,那么系统会将多个过滤器组合在一起,形成一个过滤器链,系统会自动安排请求穿越整个链路,除非我们在其中的过滤器中不进行下一步传递。而且,过滤器不限于过滤servlet,它可以过滤所有的访问请求,比如静态html,图片等。

客户端发送过来的请求会先经过过滤器处理,再到达目标Servlet,响应时,原路返回之前途径过的过滤器,后拦截的先响应。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fbfaRCk0-1662864967259)(E:\MD笔记\笔记图片\image-20220911095455548.png)]

二、过滤器的实现

通过实现servlet-api中的filter接口,即可实现过滤器,通过@WebFilter指定过滤的访问请求即可。

注解:

public @interface WebFilter {
    String description() default "";

    String displayName() default "";

    WebInitParam[] initParams() default {}; //初始化参数,示例:initParams ={@WebInitParam(name="charset",value="UTF-8")}

    String filterName() default "";

    String smallIcon() default ""; 

    String largeIcon() default "";

    String[] servletNames() default {}; //指定需要拦截的servlet的名称

    String[] value() default {}; // 指定需要过滤(被拦截)的请求地址,必须 / 开头,支持多个

    String[] urlPatterns() default {}; //等价value,指定需要过滤(被拦截)的请求地址,必须 / 开头

    DispatcherType[] dispatcherTypes() default {DispatcherType.REQUEST}; //转发调度的类型,默认为Request

    boolean asyncSupported() default false;
}

过滤器Filter接口:

public interface Filter {
    void init(FilterConfig var1) throws ServletException; //初始化一个过滤器

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException; //执行过滤业务规则,并指定是否放行:传递给下一个过滤器或目标资源

    void destroy(); //销毁
}

自定义过滤器,拦截所有请求,解决中文乱码问题:


@WebFilter(value = "/*",filterName = "EncodeFilter",displayName = "编码过滤器",initParams ={@WebInitParam(name="charset",value="UTF-8")})
public class EncodeFilter implements Filter {

    private String charset;
    @Override
    public void init(FilterConfig filterConfig) {  //每个过滤器都只初始化 1 次
        //通过 过滤器配置对象,获取到配置参数
        charset=filterConfig.getInitParameter("charset");
        System.out.println("EncodeFilter 过滤器完成初始化。。。");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("EncodeFilter 拦截到请求:"+ servletRequest.getServerName());

        servletRequest.setCharacterEncoding(this.charset);
        servletResponse.setContentType("text/html;charset=utf-8");

        filterChain.doFilter(servletRequest,servletResponse);//请求通过后,一定要手动放行

        System.out.println("响应再次经过EncodeFilter这里");
    }

    @Override
    public void destroy() { //每个过滤器都只初始化 1 次
        System.out.println("EncodeFilter 过滤器销毁了。。。");
    }
}

三、过滤器的生命周期

1、容器启动时会自动初始化所有的过滤器,调用他们的init方法,且仅初始化1次。

2、每次请求来访,都将调用doFilter方法进行过滤处理,并由业务规则判断是否放行。

3、容器关闭时,所有过滤器都被销毁,调用容器的destory,且仅销毁1次。先初始化的过滤器也先被销毁。

过滤器链上,过滤器的执行顺序:根据过滤器的名称排序,前面的先执行,如EncodeFilter 优先TokenFilter。

四、过滤器匹配模式

通过url设置拦截请求时有三种模式:

  • 精确模式:如:/index.jsp、 /myservlet ,全名匹配
  • 后缀拦截模式:如:“ *.jsp”、“* *.do”
  • 通配符(*)拦截模式: 拦截所有请求:“/*” ,拦截/a/b /路径下所有请求:/a/b/*
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值