返回符杰博客列表

Tiny学习笔记(二)

发布于 7月前

今天来看看一个请求是如何最终进入action,当我从浏览器发起请求时,请求会最先到tinyhttpFilter的dofilter进行处理。

blob.png

在进入doFilter函数后,tiny过滤器首先将request包装成可重复读的MultipleReadServletRequest。为何要转呢,在通常情况下,java的io一般只允许读一次,意思就是对于一个inputstream,我第一次读取了5个字节,那么我下次读取就是5个字节之后,这对一次处理io当然没有问题。但是如果在web工程里多个地方如果要用到servleinputstream就有问题了,比如第一个过滤器获取了inputstream,进行操作后,第二个过滤器发现获取的流不能从头开始读就很尴尬了。这个时候本可以在每次读取前进行reset操作,但是servletinputstream并不支持这个方法(不太清楚这样设计的意图),所以如果需要重复度,需要自己去继承servletInputstream。tiny过滤器一开始就将request包装成可重复读取的MultipleReadServletRequest(这一点倒是在配置文件中能设定CAN_REPEAT_READ的数值)。那就看看MultipleReadServletRequest这个是如何包装request对象的。

blob.png

可以看到,在MultipleReadServletRequest中对getInputstream这个方法进行了重写(request其他方法照旧),写了一个bufferedservletinputstream的静态内部类继承自servletInputstream。

blob.png

从这个方法可以看出如果第一次读,则从request中把输入流拿出来放在tiny自己实现的bytearrayinputstream中,让我们来来tiny实现的bytearrayinputstream

blob.png

和jdk自带的bytearrayinputstream最主要的区别就是去除了synchronized关键字,这意味这个流不是线程安全的,但是,对于一个web工程来说,每一个用户对应一个request对应一个输入流,而过滤器拦截器action对request的处理又是串行的,基本上不存在并发处理输入流的场景,所以在这里去除锁应该是对运行效率的一种考虑。这个流同时实现了reset方法,也就实现了对request可重复读的处理。


 
相关信息
     标签
       附件
      文件 标题 创建者

      评分 0次评分

      日程