手把手带你写一个 MiniTomcat
郭屹
前 Sun Microsystems Java 研发工程师
1792 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 22 讲
开篇词 (1讲)
手把手带你写一个 MiniTomcat
15
15
1.0x
00:00/00:00
登录|注册

13|Filter与Listener:如何实现过滤和持续监听?

你好,我是郭屹。今天我们继续手写 MiniTomcat。
上一节课我们实现了 Pipeline 和 Valve,这样我们在流程走通的前提下,可以在每一层 Container 之间增加权限校验、日志打印、错误输出等自定义的处理逻辑。此外我们引入了责任链这一设计模式,来依次调用这些处理逻辑。
这节课我们继续来完善 MiniTomcat,我们计划引入两个组件——Filter(过滤器)以及 Listener(监听器),并且还是使用经典的职责链模式。
过滤器可以检查请求对象以及返回对象,并通过请求对象和返回对象的包装类进行修改,而且多个过滤器之间可以串联,就像流水线一样一层层进行过滤,协同起来组装成最终的请求对象和响应对象。
而监听器的存在是为了配合我们目前已有的 Container、Session 等机制,通过监听这些机制的事件,比如启动、超时、结束等,更好地对服务器进行处理。
我们一起来动手实现。

项目结构

这节课我们主要新增了 Filter 相关处理方法类,还有 Container、Instance 与 Session 的事件和监听器,具体类的功能我们后面会详细介绍。你可以看一下现在的项目结构。
MiniTomcat
├─ src
│ ├─ main
│ │ ├─ java
│ │ │ ├─ com
│ │ │ │ ├─ minit
│ │ │ │ │ ├─ connector
│ │ │ │ │ │ ├─ http
│ │ │ │ │ │ │ ├─ DefaultHeaders.java
│ │ │ │ │ │ │ ├─ HttpConnector.java
│ │ │ │ │ │ │ ├─ HttpHeader.java
│ │ │ │ │ │ │ ├─ HttpProcessor.java
│ │ │ │ │ │ │ ├─ HttpRequestImpl.java
│ │ │ │ │ │ │ ├─ HttpRequestLine.java
│ │ │ │ │ │ │ ├─ HttpResponseImpl.java
│ │ │ │ │ │ │ ├─ ServletProcessor.java
│ │ │ │ │ │ │ ├─ SocketInputStream.java
│ │ │ │ │ │ │ ├─ StatisResourceProcessor.java
│ │ │ │ │ │ ├─ HttpRequestFacade.java
│ │ │ │ │ │ ├─ HttpResponseFacade.java
│ │ │ │ │ ├─ core
│ │ │ │ │ │ ├─ ApplicationFilterChain.java
│ │ │ │ │ │ ├─ ApplicationFilterConfig.java
│ │ │ │ │ │ ├─ ContainerBase.java
│ │ │ │ │ │ ├─ ContainerListenerDef.java
│ │ │ │ │ │ ├─ FilterDef.java
│ │ │ │ │ │ ├─ FilterMap.java
│ │ │ │ │ │ ├─ StandardContext.java
│ │ │ │ │ │ ├─ StandardContextValve.java
│ │ │ │ │ │ ├─ StandardPipeline.java
│ │ │ │ │ │ ├─ StandardWrapper.java
│ │ │ │ │ │ ├─ StandardWrapperValve.java
│ │ │ │ │ ├─ logger
│ │ │ │ │ │ ├─ Constants.java
│ │ │ │ │ │ ├─ FileLogger.java
│ │ │ │ │ │ ├─ LoggerBase.java
│ │ │ │ │ │ ├─ SystemErrLogger.java
│ │ │ │ │ │ ├─ SystemOutLogger.java
│ │ │ │ │ ├─ session
│ │ │ │ │ │ ├─ StandardSession.java
│ │ │ │ │ │ ├─ StandardSessionFacade.java
│ │ │ │ │ ├─ startup
│ │ │ │ │ │ ├─ BootStrap.java
│ │ │ │ │ ├─ util
│ │ │ │ │ │ ├─ CookieTools.java
│ │ │ │ │ │ ├─ StringManager.java
│ │ │ │ │ │ ├─ URLDecoder.java
│ │ │ │ │ ├─ valves
│ │ │ │ │ │ ├─ AccessLogValve.java
│ │ │ │ │ │ ├─ ValveBase.java
│ │ │ │ ├─ Connector.java
│ │ │ │ ├─ Container.java
│ │ │ │ ├─ ContainerEvent.java
│ │ │ │ ├─ ContainerListener.java
│ │ │ │ ├─ Context.java
│ │ │ │ ├─ InstanceEvent.java
│ │ │ │ ├─ InstanceListener.java
│ │ │ │ ├─ Logger.java
│ │ │ │ ├─ Pipeline.java
│ │ │ │ ├─ Request.java
│ │ │ │ ├─ Response.java
│ │ │ │ ├─ Session.java
│ │ │ │ ├─ SessionEvent.java
│ │ │ │ ├─ SessionListener.java
│ │ │ │ ├─ Valve.java
│ │ │ │ ├─ ValveContext.java
│ │ │ │ ├─ Wrapper.java
│ │ ├─ resources
│ ├─ test
│ │ ├─ java
│ │ │ ├─ test
│ │ │ │ ├─ HelloServlet.java
│ │ │ │ ├─ TestFilter.java
│ │ │ │ ├─ TestListener.java
│ │ │ │ ├─ TestServlet.java
│ │ ├─ resources
├─ webroot
│ ├─ test
│ │ ├─ HelloServlet.class
│ │ ├─ TestFilter.class
│ │ ├─ TestListener.class
│ │ ├─ TestServlet.class
│ ├─ hello.txt
├─ pom.xml
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文详细介绍了在MiniTomcat中实现过滤器(Filter)和监听器(Listener)的过程。通过引入责任链模式,过滤器可以检查和修改请求和返回对象,多个过滤器可以协同工作,监听器则通过监听事件来更好地处理服务器。文章还介绍了项目结构和新增的相关处理方法类,读者可以通过本文了解MiniTomcat中过滤和持续监听的技术特点。 在过滤器的实现过程中,文章详细介绍了Filter、FilterConfig和FilterChain三个接口的定义,以及ApplicationFilterConfig类的实现。通过这些内容,读者可以深入了解MiniTomcat中过滤器的工作原理和实现方式。此外,文章还介绍了如何在MiniTomcat中实现FilterMap类和URLDecoder工具类,以及对StandardContext进行调整,新增了过滤器的配置和处理。 在监听器的实现过程中,文章介绍了如何在BootStrap类中配置了监听器信息,并通过测试文件夹定义了测试类来验证监听器的实现。通过这些内容,读者可以了解MiniTomcat中配置和处理过滤器映射,以及监听器的使用方法。 总的来说,本文通过详细的代码实现和解释,帮助读者深入了解了MiniTomcat中过滤器和监听器的实现原理和技术特点,对于想要深入学习MiniTomcat内部工作原理的开发人员来说,是一篇非常有价值的技术文章。文章内容涵盖了责任链模式、过滤器和监听器的实现原理,以及在MiniTomcat中的具体应用,为读者提供了深入学习和应用的价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手带你写一个 MiniTomcat》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(2)

  • 最新
  • 精选
  • HH🐷🐠
    抓大放小, 个人觉得核心流程: ApplicationFilterChain.doFilter() --> ApplicationFilterChain.internalDoFilter() --> Filter.doFilter() --> ApplicationFilterChain.doFilter() 一个环状; 入口 StandardWrapperValve , 出口是否有下一个Filter。

    作者回复: 很好。 再考虑一下valve之间的次序,和filter之间的次序,是一样的吗?

    2024-01-07归属地:广东
    2
  • peter
    请教老师几个问题: Q1:BootStrap代替了HttpServer吗?为什么这么做? Q2:Filter、Listener可以扩展吗? 比如,用户自定义Filter、Listener,是否支持? Q3:用 ArrayList 存放所有的 filter和listener,有什么考虑? 用Map不行吗? Q4:对于Filter,是FilterChain最后调用servlet吗? 按说不应该由Filter调用servlet,而是由一个更高层的一个东西来调用,类似于控制器或调度器一类的来调用。 Q5:有浏览器上的servlet吗? 我们这里说的servlet,都是运行在后端。我听说有运行在浏览器上的servlet,是否有?

    作者回复: HttpServer这个名字含义是服务器,Bootstrap含义是启动,功能的划分,启动的概念更加贴切 Filter/Listener是规范定义的,必须符合规范,只能自己实现不能修改接口 用Arraylist是这种场景:有次序,不需要名字。所以这里用的arraylist 是filterchain最后调用servlet,这是规范规定的 从术语上,servlet是后端,不是浏览器上的,远古时代,浏览器上有applet

    2024-01-07归属地:北京
收起评论
显示
设置
留言
2
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部