前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Tomcat Filter 自己动手实现

Tomcat Filter 自己动手实现

作者头像
java404
发布2018-05-18 12:27:35
1.8K0
发布2018-05-18 12:27:35
举报
文章被收录于专栏:java 成神之路java 成神之路

Filter 简介

Filter也称之为过滤器,它是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

Filter功能

在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

如何借助Filter实现拦截功能

Filter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源进行拦截后,Web服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:

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

下面根据tomcat中的 filter 自己实现一个Filter

参考:Tomcat Filter 源码分析

Filter使用设计模式中的责任链设计模式

手写 Filter过滤器 源码实现

先看下有哪些类,如下图:

1. Filter 接口

Filter.java
代码语言:javascript
复制
public interface Filter {
    public void doFilter(Request req, Response res, FilterChain filterChain);
}

2. 过滤链实现类

FilterChain.java

这个类是过滤器链的核心类

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;

public class FilterChain{
    
    //目标servlet
    private Servlet servlet;
    //将要执行的过滤器下标(过滤器链)
    private int pos = 0;
    
    //存储过滤器的容器(tomcat中使用的是一个数组进行存储的)
    private List<Filter> list = new ArrayList<>();
    
    public void doFilter(Request req, Response res) {
        //判断是否还有要执行的filter
        if(pos<list.size()){
            //每次调用过滤器链的doFilter时,都要将pos坐标+1
            //注意pos++的位置,如果调用完doFilter在pos++ 就出现死循环了
            list.get(pos++).doFilter(req, res, this);
        }else{
            //如果所有的过滤器都执行完成则执行servlet
            getServlet().service(req, res);
        }
    }

    //向过滤器链中添加过滤器
    public void addFilter(Filter filter){
        list.add(filter);
    }

    //设置servlet
    public void setServlet(Servlet servlet) {
        this.servlet = servlet;
    }

    public Servlet getServlet() {
        return servlet;
    }
}

3. 模拟 web 中的 Servlet

Servlet.java
代码语言:javascript
复制
public class Servlet {
    public void service(Request req, Response res){
        System.out.println("service ok----------");
    }
}

4. 自定义的过滤器

EncodeFilter.java

模拟实现编码转换过滤器

代码语言:javascript
复制
public class EncodeFilter implements Filter{

    @Override
    public void doFilter(Request req, Response res, FilterChain chain) {
        //在 servlet 之前执行
        System.out.println("encode start ...");
        
        chain.doFilter(req, res);
        
        //在 servlet 之后执行
        System.out.println("encode end ...");
    }

}
LogFilter.java

模拟实现日志过滤器

代码语言:javascript
复制
public class LogFilter implements Filter{

    @Override
    public void doFilter(Request req, Response res, FilterChain chain) {
        //在 servlet 之前执行
        System.out.println("log start ...");
        
        chain.doFilter(req, res);
        
        //在 servlet 之后执行
        System.out.println("log end ...");
    }

}

5. 模拟 servlet 中 request 和 response 对象

这里Request类和Response类,没有实现任何方法,只是为模拟Servlet中的参数而创建的类。

Request.java
代码语言:javascript
复制
public class Request {}
Response.java
代码语言:javascript
复制
public class Response {}

6. 启动方法

Main.java
代码语言:javascript
复制
public class Main {
    public static void main(String[] args) {
        FilterChain chain = new FilterChain();
        //设置要执行的Servlet
        chain.setServlet(new Servlet());
        
        //根据url-pattern的匹配规则 向 FilterChain中添加过滤器
        //这些Filter
        chain.addFilter(new LogFilter());
        chain.addFilter(new EncodeFilter());
        
        //执行
        chain.doFilter(new Request(), new Response());
    }
}

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.09.03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Filter 简介
  • Filter功能
  • 如何借助Filter实现拦截功能
  • 手写 Filter过滤器 源码实现
  • 1. Filter 接口
    • Filter.java
    • 2. 过滤链实现类
      • FilterChain.java
      • 3. 模拟 web 中的 Servlet
        • Servlet.java
        • 4. 自定义的过滤器
          • EncodeFilter.java
            • LogFilter.java
            • 5. 模拟 servlet 中 request 和 response 对象
              • Request.java
                • Response.java
                • 6. 启动方法
                  • Main.java
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档