然如欲以求日志中显有一部分特有的音。但只要需要在呼吁日志被展示出有些蓄意的消息。过滤器(Filter)是 Java 组件。

运过滤器改进应用程序

用过滤器改进应用程序

Filtering

过滤器(Filter)是 Java 组件,
允许运行过程遭到改进入资源的恳求和资源归的应中之管用载荷和 header
信息。

本章描述了 Java Servlet v3.0 API
类和方法,它提供了一样种轻量级的框架用于过滤动态和静态内容。还打
陈了争以 Web 应用配置 Filter和她贯彻的预定和语义。

网上供servlet过滤器的API文档在。过滤器的布置语法由第14段“部署描述吻合”中的布描述符模式给起。阅读本章时,读者应使用这些来当参照。

如出一辙、过滤器的目的

无异于、过滤器的目的

1. 呀是过滤器

过滤器是相同段落可选用的代码,它好转换HTTP请求、响应与头信息的情。过滤器通常不会见像servlet那样创建响应或响应请求,而是修改或者调整资源的要,并修改要调整资源的响应。

过滤器可以作用被动态或者静态内容。为了本章的目的,动态和静态内容为称之为Web资源。

于需要采取过滤器的开发人员可用之功用类别如下:

  • 资源的拜访请求之前调用它。
  • 一个资源要的拍卖之前调用。
  • 经包定制版本的请对象对要求头和数量的改动
  • 经过提供定制版本的应对象对响应头和应数据的改。
  • 资源的调用的后拦。
  • 盖指定的依次通过零,一个要多只过滤器操作servlet、servlet、组要静态内容。

过滤器是可以阻止访问资源的请求、资源的应或者同时阻止两者的利用组件。过滤器可以检测及修改要和响应,同时也得以拒绝、重定向或转向呼吁。javax.servlet.Filter接口实现了过滤器技术,使用HttpServletRequest和HttpServletResponse。过滤器可以于安排描述符中因因为编程的方宣示,它们得以有初始化参数并且可以看ServletContext。

过滤器是好阻止访问资源的恳求、资源的应或者同时拦两者的行使组件。过滤器可以检测及改要和响应,同时也得以拒绝、重定向或转发呼吁。javax.servlet.Filter接口实现了过滤器技术,使用HttpServletRequest和HttpServletResponse。过滤器可以以安排描述符中因因为编程的道宣示,它们得以来初始化参数并且可以拜ServletContext。

1.1 过滤器组件例子
  • Authentication filters
  • Logging and auditing filters
  • Image conversion filters
  • Data compression filters
  • Encryption filters
  • Tokenizing filters
  • Filters that trigger resource access events
  • XSL/T filters that transform XML content
  • MIME-type chain filters
  • Caching filters

日志过滤器

日记过滤器

2.首要概念

本章描述了过滤器模型的关键概念。
应用程序开发人员通过落实javax.servlet.Filter接口创建一个过滤器,并提供一个非带参数的官构造函数。该类及构建Web
应用之静态资源以及 Servlet 打包在 Web
应用归档文件中。在安排描述符中使用要素声明过滤器。通过当布局描述符中定义<filter-mapping>要素,可以吗过滤器或过滤器集合配置调用。可以采取
servlet 的
逻辑名把过滤器映射到一个特定的 servlet,或者采用 URL
模式将过滤器映射到平组 Servlet 和静态内容资源。

于应用程序开发被,需要记录有应用程序的要和每个请求的结果(状态码,长度等其他信息)。通常Web容器提供了央日志的编制,但倘若用以求日志被形有一部分特有的音,可以行使过滤记录请求。

每当应用程序开发被,需要记录有应用程序的呼吁与每个请求的结果(状态码,长度等其它信息)。通常Web容器提供了要日志的机制,但假如要在呼吁日志中展示出一些有意识的音信,可以用过滤记录请求。

2.1 过滤器生命周期

The doFilter method of a filter will typically be implemented following
this or some subset of the following pattern:
每当布局Web应用程序之后,在呼吁导致容器访问Web资源之前,容器必须稳定要下于Web资源的过滤器列表,如下所陈述。容器必须保证其都也列表中之每个过滤器实例化了一个适当类的过滤器,并调用它的init(FilterConfig
config)方法。这个过滤器可能会见丢弃来一个可怜来代表她不克正常干活。如果大类型也UnavailableException,则容器可以检查好的isPermanent属性,并于稍后底日选择重试过滤器。

每当配置描述符中,每个<filter>声明只生一个实例被实例化到容器的每个JVM中。容器提供过滤器部署描述符中声明的过滤器配置,用于Web应用程序的ServletContext的援,以及初始化参数集聚。

当容器接收至一个传播请求时,它将于列表中获得第一独过滤器实例,并调用它的doFilter方法,传入ServletRequest和ServletResponse,并引用它用利用的FilterChain对象。

过滤器的doFilter方法通常会仍以下模式的之一子集实现:

  1. 欠办法检查请求的header。

  2. 拖欠措施可据此定制的ServletRequest或HttpServletRequest实现来包装请求对象,以改要求头或数量。

  3. 该措施可拿响应对象封装到该doFilter方法中,并定制实现ServletResponse或HttpServletResponse来窜响应头或数额。

  4. 过滤器可以调用过滤器链中之生一个实体。下一个实体可能是任何一个过滤器,或者如调用的过滤器是以此链的部署描述符中配置的尾声一个过滤器,那么下一个实体就是目标Web资源。下一个实体的调用是通过调用FilterChain对象上的doFilter方法来贯彻之,并于求和响应中传送它或许早已创造的包版。过滤器链的doFilter方法的兑现,由容器提供,必须在过滤器链中一定下一个实体,并调用它的doFilter方法,传入适当的恳求和响应对象。或者,过滤器链可以阻碍请求,而未是调用调用下一个实体,让过滤器负责填充响应对象。service方法要在和利用于servlet的持有过滤器相同之线程中运行。

  5. 于调用链中之下一个过滤器之后,过滤器可以检查响应头。

  6. 抑或,过滤器可能会见扔来一个很来指示处理面临之荒唐。如果过滤器在其doFilter处理过程中丢掉来一个无法用的那个,容器就非能够尝继续本着过滤器链进行拍卖。如果不行不是永久性的,它可以选于今后又尝试任何链条。

  7. 当调用链中之末梢一个过滤器时,将造访的下一个实体是链末端的靶子servlet或资源。

  8. 当过滤器实例可以吃容器从劳动着删除之前,容器必须首先调用过滤器上的destroy方法,以使过滤器能够自由其他资源并履行外清理操作。

征过滤器

证明过滤器

2.2卷入请求与应

过滤概念的着力是包裹请求或响应的定义,以便其可以挂作为来实行过滤任务。在这模型中,开发人员不仅起能力覆盖要与应对象上的水土保持措施,而且还能够提供合吃特定筛选任务之新API,从而使过滤器或目标web资源沿着链向下。例如,开发人员可能想将响应对象扩大及输出流或摹写入器的再次胜级别之出口对象,例如允许以DOM对象写回客户机的API。

为支持这种类型的过滤器,容器必须支持以下要求。当一个过滤器调用容器的过滤器链上的doFilter方法实现着,容器必须确保它通过过滤器链中之产一个实体,或到对象web资源而过滤器链中之尾声一个底伸手和应对象,是由此调用过滤器传递至doFilter方法的同一之靶子。

包装器对象标识的等同要求适用于从servlet或过滤器到RequestDispatcher的调用。或RequestDispatcher向前向上。包括,当调用者包装请求或响应对象时。在这种情形下,被调用的servlet所见到的恳求与应对象要是由此调用servlet或过滤器传入的同一之包装器对象。

假设用确保只有授权用户才足以拜应用程序,通常可以检查每个请求的消息,保证用户就登录,过滤器可以透过以证明和授权操作集中到一个职位的章程如工作易得简单。

设需要保证只有授权用户才好看应用程序,通常可以检查每个请求的音讯,保证用户都报到,过滤器可以由此将说明和授权操作集中到一个职的办法要办事换得简单。

2.3 过滤器环境

以部署描述符中使用<initparams>元素,可以将同一组初始化参数关联到一个过滤器。这些参数的名和值可以透过getInitParameter和getInitParameterNames方法以运作时通过过滤器的FilterConfig对象开展筛选。此外,FilterConfig提供了针对性Web应用程序的ServletContext的造访,用于加载资源、记录功能,以及以ServletContext的性列表中存储状态。过滤器和过滤器链末端的目标servlet或资源要以同之调用线程中实行。

减去和加密过滤器

缩减和加密过滤器

2.4 在一个Web应用中filter的配置

过滤器是由此@WebFilter注释定义之,如以正儿八经的第8-72页中定义之“@WebFilter”或用安排描述符中的
<filter>元素 。在这个因素被,程序员声明如下:

  • 过滤器名称:用于过滤器映射到一个servlet或URL

  • 过滤器类:容器使用来辨别过滤器类型

  • 初始化:一个过滤器的初始化参数

可选地,程序员可以指定图标、文本描述和工具操作的来得名称。容器必须实例化定义在配备描述符中每个过滤器声明的过滤器的Java类的一个实例。因此,如果开发人员为同一个过滤器类生成稀独过滤器声明,那么容器将实例化同一个过滤器类的少只实例。

下是一个过滤器声明的例子:

<filter>
<filter-name>Image Filter</filter-name>
<filter-class>com.example.ImageServlet</filter-class>
</filter>

于配备描述符中声明了过滤器之后,汇编器使用filter-mapping>元素来定义Web应用程序中之servlet和静态资源。过滤器可以利用<servlet-name>元素和servlet关联。例如,下面的代码示例将图像过滤器过滤器映射到ImageServlet
servlet:

<filter-mapping>
<filter-name>Image Filter</filter-name>
<servlet-name>ImageServlet</servlet-name>
</filter-mapping>

Filters can be associated with groups of servlets and static content
using the <urlpattern> style of filter mapping:

<filter-mapping>
<filter-name>Logging Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

此地,日志过滤器应用于Web应用程序中之有着servlet和静态内容页,因为每个请求URI都相当“/*”URL模式。

当以<url-pattern>样式处理<filter-mapping>元素时,容器必须确定是不是配合请求URI,使用第12回中定义的路映射规则,“将呼吁映射到servlet”。

每当构建用于特定请求URI的淘器链时,容器使用的依次如下:

  1. 率先,<url-pattern>匹配的过滤器映射与这些因素以配备描述符中出现的逐一相同。
  2. 连片下去,<servlet-name>匹配的过滤器映射与这些元素于配置描述符中出现的顺序相同。

苟一个筛选映射包含了<servlet-name>
和<url-pattern>,那么容器必须用罗映射扩展及大半只筛选映射(每个<servletname>
and <url-pattern>),保存<servlet-name> and
<urlpattern>元素的逐一。例如,下面的筛选器映射:

<filter-mapping>
<filter-name>Multiple Mappings Filter</filter-name>
<url-pattern>/foo/*</url-pattern>
<servlet-name>Servlet1</servlet-name>
<servlet-name>Servlet2</servlet-name>
<url-pattern>/bar/*</url-pattern>
</filter-mapping>

is equivalent to:

<filter-mapping>
<filter-name>Multipe Mappings Filter</filter-name>
<url-pattern>/foo/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Multipe Mappings Filter</filter-name>
<servlet-name>Servlet1</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>Multipe Mappings Filter</filter-name>
<servlet-name>Servlet2</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>Multipe Mappings Filter</filter-name>
<url-pattern>/bar/*</url-pattern>
</filter-mapping>

至于过滤器链顺序的求表示容器在吸纳至传播请求时照如下方式处理要:
■根据第126页上的“映射规范”的条条框框标识目标Web资源。
■如果在通过servlet名称匹配的过滤器并且Web资源有着<servletname>,那么容器会依照安排描述符中声明的各个构建匹配的过滤器链。该链中之末段一个过滤器对应于最后一个<servlet-name>匹配过滤器,并且是调用目标Web资源的过滤器。
■如果是使用<url-pattern>匹配的过滤器并且<url-pattern>根据第12.2节“映射规范”的规则匹配请求URI,则容器会构建匹配过滤器的<url-pattern>链和配置描述符中声明的逐条相同。此链中之末尾一个过滤器是其一恳请URI的安排描述符中的结尾一个<url-pattern>匹配过滤器。该链中之最后一个过滤器是调用<servlet-name>匹配链中的第一独过滤器的过滤器,或者调用目标Web资源(如果没有)。

展望强性能Web容器将缓存过滤器链,以便其不需要依照每个请求计算其。

留存正在网络带来富有限而CPU资源雄厚的图景,通常以数额传之前对数码进行压缩。过滤器可以于接到请求时,请求保持无变换,但于响应返回给用户时时,使用过滤器可以削减相应对象。

在在网络带来富有限而CPU资源丰富的场面,通常以多少传之前对数据开展削减。过滤器可以当收取请求时,请求保持无变换,但每当响应返回给用户时时,使用过滤器可以减去相应对象。

2.5 Filters and the RequestDispatcher

自Java Servlet规范2.4本子来说的初长效益是会配置为呼吁调度器(request
dispatcher)的forward()和include()调用的过滤器。
通过当布局描述符中使用新的<dispatcher>元素,开发人员可以指出过滤器映射是否要当以下状况下将过滤器应用被要:
1.告直接来源于客户端。这是因为具有值REQUEST的<dispatcher>元素或尚未外<dispatcher>元素指示。
2.央在吃代表相当配<url-pattern>或<servlet-name>的Web组件的要调度程序下下forward()调用所拍卖。这由拥有值FORWARD的<dispatcher>元素指示。
3.求在代表匹配<url-pattern>或<servlet-name>的Web组件的要分派器下下include()进行处理。
呼叫。这是因为一个价值吗INCLUDE的<dispatcher>元素表示。
4.该要在下第112页上的“错误处理”中指定的一无是处页机制处理也同<url-pattern>匹配的错误资源。这是因为具有值ERROR的<dispatcher>元素指示。
5.该请求在使用第10页上之“异步处理”中指定的异步上下文分派机制,通过调度呼叫处理及Web组件。这是因为具有值ASYNC的<dispatcher>元素指示。
6.还是上述1,2,3,4要么5之别组合。
例如:

<filter-mapping>
<filter-name>Logging Filter</filter-name>
<url-pattern>/products/*</url-pattern>
</filter-mapping>

见面招致日志过滤器被客户端启动的/products/..请求调用,但切莫以请分派器调用之下调用,其中要分派器具有路径始于/
products/…。LoggingFilter将在伸手最初的调度以及还原的恳求时让调用。
以下代码:

<filter-mapping>
<filter-name>Logging Filter</filter-name>
<servlet-name>ProductServlet</servlet-name>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>

拿促成日志过滤器不会见受客户端请求调用到ProductServlet,也不见面于呼吁dispatcher
forward()调用下调用ProductServlet,而是会以求调度程序include()调用中调用,其中要分派器的名号为ProductServlet开始。下面的代码:

<filter-mapping>
<filter-name>Logging Filter</filter-name>
<url-pattern>/products/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

以促成Logging
Filter被/products/…开头的乞求与为/products/…开头的恳求分发器forward()调用下调用。
最终,以下代码用特别之servlet名“*”

<filter-mapping>
<filter-name>All Dispatch Filter</filter-name>
<servlet-name>*</servlet-name>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>

在以名或按路径获取的拥有请求分派器 forward()调用时欠代码用促成 All
Dispatch Filter 被调用。

错误处理过滤器

错误处理过滤器

对于Web用用程序而言,出现谬误,是一个HTTP响应代码500,一般还见面陪在一个屡见不鲜的HTML页面,写着“Internal
Server
Error”以及部分诊断信息。对于当本土运行的应用程序对开发者是有效之,但是对于远程的应用程序来说是休必要之。需要经过滤器给用户展示有更团结之同通用的错误处理页面,并记下必要之错误信息。

对此Web用用程序而言,出现谬误,是一个HTTP响应代码500,一般还会伴随着一个普通的HTML页面,写着“Internal
Server
Error”以及有诊断信息。对于以本地运行的应用程序对开发者是有效的,但是于远程的应用程序来说是未必要之。需要经过过滤器给用户展示有越来越和睦之跟通用的错误处理页面,并记录必要之错误信息。

第二、创建、声明和投过滤器

次、创建、声明和投过滤器

创建过滤器就是贯彻Filter接口一样,过滤器在初始化的时段以调用init方法,他可以拜过滤器的安排初始化参数与ServletContext。当呼吁进入到过滤器中,doFilter方法将会见让调用,它提供了针对ServletRequest、ServletResponse和FilterChain对象的走访。在doFilter中,可以拒绝请求或者调用FilterChain对象的doFilter方法,可以打包请求与应对象。

创办过滤器就是促成Filter接口一样,过滤器在初始化的时光用调用init方法,他得以拜过滤器的布局初始化参数和ServletContext。当呼吁进入及过滤器中,doFilter方法将会让调用,它提供了对ServletRequest、ServletResponse和FilterChain对象的访。在doFilter中,可以拒绝请求或者调用FilterChain对象的doFilter方法,可以打包请求与响应对象。

过滤器链

过滤器链

尽管就生一个Servlet可以拍卖要,但是好用群之过滤拦截请求。在过滤器链中各一个过滤器接受上的恳求并将它们传递及下一个过滤链中,直到所有匹配的过滤器都处理好,最终还以它们传到Servlet中。调用FilterChain.doFilter()将触发过滤器链的随地实施。如果手上的过滤器没有调用FilterChain.doFilter(),将将控制权返回值Servlet容器被。

尽管就生一个Servlet可以拍卖要,但是好采用多之过滤拦截请求。在过滤器链中各一个过滤器接受上的要并拿它们传递至下一个过滤链中,直到所有匹配的过滤器都处理就,最终还将它们传播Servlet中。调用FilterChain.doFilter()将触及过滤器链的络绎不绝推行。如果手上底过滤器没有调用FilterChain.doFilter(),将将控制权返回值Servlet容器中。

映射到URL模式和Servlet名称

映射到URL模式和Servlet名称

及Servlet一样,过滤器可以给射到URL模式,这会控制谁要如何过滤器将截留某个请求。任何匹配有过滤器的URL模式的恳求在吃匹配的Servlet处理之前用率先进入该过滤器,通过利用URL模式,不仅可以阻挡Servlet请求,还足以阻止任何资源。

以及Servlet一样,过滤器可以被射到URL模式,这会控制谁要如何过滤器将截留某个请求。任何匹配有过滤器的URL模式之乞求在受匹配的Servlet处理之前用率先进入该过滤器,通过以URL模式,不仅可阻止Servlet请求,还足以阻碍任何资源。

但是当现在已经发生差不多个URL已经照到Servlet上,并且期待某些过滤器映射到这些URL上。与照到URL上反,可以将这些过滤器映射到一个还是多只Servlet名称上。

但是当现在曾经产生差不多只URL已经照到Servlet上,并且愿意某些过滤器映射到这些URL上。与照到URL上反,可以拿这些过滤器映射到一个还是多单Servlet名称上。

1.每当配备描述符中使用<filter>和<filter-mapping>元素:

1.以布局描述符中使用<filter>和<filter-mapping>元素:

    <filter>
        <filter-name>filterA</filter-name>
        <filter-class>com.wrox.AnyRequestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filterA</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>filterA</filter-name>
        <filter-class>com.wrox.AnyRequestFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>filterA</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

于宣称了过滤器之后,可以用其映射到任意数目的URL或Servlet名称。当然过滤器URL映射还足以蕴涵通配符。

以声明了过滤器之后,可以以它映射到自由数目的URL或Servlet名称。当然过滤器URL映射还得蕴涵通配符。

2.采取注解声明与投过滤器

2.使用注解声明与投过滤器

@WebFilter{
    filterName = "myFilter",
    urlPatterns = {"/foo","/bar/*"},
    serVletNames = {"myServlet"},
    dispatcherTypes = {DispatcherType.REQUEST,         
    DispatcherType.ASYNC}    
}
@WebFilter{
    filterName = "myFilter",
    urlPatterns = {"/foo","/bar/*"},
    serVletNames = {"myServlet"},
    dispatcherTypes = {DispatcherType.REQUEST,         
    DispatcherType.ASYNC}    
}

而是未可以针对针对过滤器链上之过滤器进行排序

可是未得以本着针对性过滤器链上的过滤器进行排序

其三、过滤器排序

老三、过滤器排序

过滤器的逐一决定了过滤器在过滤器链中出现的职,这里将会晤动用安排描述符来进行布置,因为注解无法进展排序配置。

过滤器的相继决定了过滤器在过滤器链中出现的职务,这里拿会使用安排描述符来进行配置,因为注解无法进行排序配置。

URL模式映射和Servlet名称映射,匹配请求的过滤器将据她出现于安排描述符或者编程式配置中的依次上加至过滤器链中,但是要小心URL映射的过滤器优先级比Servlet名称映射到的过滤器高,由URL模式匹配的过滤器总是出现在有Servlet名称匹配的过滤器之前。

URL模式映射和Servlet名称映射,匹配请求的过滤器将按部就班她出现于布局描述符或者编程式配置中之逐条上加至过滤器链中,但是要注意URL映射的过滤器优先级比Servlet名称映射到的过滤器高,由URL模式匹配的过滤器总是出现在产生Servlet名称匹配的过滤器之前。

    <filter>
        <filter-name>filterA</filter-name>
        <filter-class>com.wrox.FilterA</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterA</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filterB</filter-name>
        <filter-class>com.wrox.FilterB</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterB</filter-name>
        <url-pattern>/servletTwo</url-pattern>
        <url-pattern>/servletThree</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filterC</filter-name>
        <filter-class>com.wrox.FilterC</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterC</filter-name>
        <url-pattern>/servletTwo</url-pattern>
    </filter-mapping>
    <filter>
        <filter-name>filterA</filter-name>
        <filter-class>com.wrox.FilterA</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterA</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filterB</filter-name>
        <filter-class>com.wrox.FilterB</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterB</filter-name>
        <url-pattern>/servletTwo</url-pattern>
        <url-pattern>/servletThree</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>filterC</filter-name>
        <filter-class>com.wrox.FilterC</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>filterC</filter-name>
        <url-pattern>/servletTwo</url-pattern>
    </filter-mapping>

立马是一个filter的实例:

立刻是一个filter的实例:

立即是拍卖着的第一只过滤器,它以记录处理要的时刻,并记下有访问应用程序的请求信息——IP地址、时间穿、请求方法等消息,finally块中是日记的操作。

即是处理中之首先单过滤器,它用记录处理要的日,并记录有访问应用程序的呼吁信息——IP地址、时间戳、请求方法齐信息,finally块中凡日记的操作。

public class RequestLogFilter implements Filter
{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException
    {
        Instant time = Instant.now();
        StopWatch timer = new StopWatch();
        try
        {
            timer.start();
            chain.doFilter(request, response);
        }
        finally
        {
            timer.stop();
            HttpServletRequest in = (HttpServletRequest)request;
            HttpServletResponse out = (HttpServletResponse)response;
            String length = out.getHeader("Content-Length");
            if(length == null || length.length() == 0)
                length = "-";
            System.out.println(in.getRemoteAddr() + " - - [" + time + "]" +
                    " \"" + in.getMethod() + " " + in.getRequestURI() + " " +
                    in.getProtocol() + "\" " + out.getStatus() + " " + length +
                    " " + timer);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void destroy() { }
}
public class RequestLogFilter implements Filter
{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException
    {
        Instant time = Instant.now();
        StopWatch timer = new StopWatch();
        try
        {
            timer.start();
            chain.doFilter(request, response);
        }
        finally
        {
            timer.stop();
            HttpServletRequest in = (HttpServletRequest)request;
            HttpServletResponse out = (HttpServletResponse)response;
            String length = out.getHeader("Content-Length");
            if(length == null || length.length() == 0)
                length = "-";
            System.out.println(in.getRemoteAddr() + " - - [" + time + "]" +
                    " \"" + in.getMethod() + " " + in.getRequestURI() + " " +
                    in.getProtocol() + "\" " + out.getStatus() + " " + length +
                    " " + timer);
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }

    @Override
    public void destroy() { }
}

 

 

相关文章