使用过滤器改进应用程序

一、过滤器的目的

过滤器是可以拦截访问资源的请求、资源的响应或者同时拦截两者的应用组件。过滤器可以检测和修改请求和响应,同时也可以拒绝、重定向或转发请求。javax.servlet.Filter接口实现了过滤器技术,使用HttpServletRequest和HttpServletResponse。过滤器可以在部署描述符中以以编程的方式声明,它们可以有初始化参数并且可以访问ServletContext。

日志过滤器

在应用程序开发中,需要记录所有应用程序的请求和每个请求的结果(状态码,长度等其它信息)。通常Web容器提供了请求日志的机制,但如果需要在请求日志中显示出一些特有的信息,可以使用过滤记录请求。

验证过滤器

如果需要确保只有授权用户才可以访问应用程序,通常可以检查每个请求的信息,保证用户已登录,过滤器可以通过将验证和授权操作集中到一个位置的方式使工作变得简单。

压缩和加密过滤器

存在着网络带宽有限而CPU资源充足的情况,通常在数据传输之前对数据进行压缩。过滤器可以在收到请求时,请求保持不变,但在响应返回给用户时,使用过滤器可以压缩相应对象。

错误处理过滤器

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

二、创建、声明和映射过滤器

创建过滤器就是实现Filter接口一样,过滤器在初始化的时候将调用init方法,他可以访问过滤器的配置初始化参数和ServletContext。当请求进入到过滤器中,doFilter方法将会被调用,它提供了对ServletRequest、ServletResponse和FilterChain对象的访问。在doFilter中,可以拒绝请求或者调用FilterChain对象的doFilter方法,可以封装请求和响应对象。

过滤器链

尽管只有一个Servlet可以处理请求,但是可以使用许多的过滤拦截请求。在过滤器链中每一个过滤器接受进入的请求并将它传递到下一个过滤链中,直到所有匹配的过滤器都处理完成,最终再将它传入Servlet中。调用FilterChain.doFilter()将触发过滤器链的持续执行。如果当前的过滤器没有调用FilterChain.doFilter(),将把控制权返回值Servlet容器中。

映射到URL模式和Servlet名称

同Servlet一样,过滤器可以被映射到URL模式,这会决定哪个或哪些过滤器将拦截某个请求。任何匹配某个过滤器的URL模式的请求在被匹配的Servlet处理之前将首先进入该过滤器,通过使用URL模式,不仅可以拦截Servlet请求,还可以拦截其它资源。

但是当现在已经有多个URL已经映射到Servlet上,并且希望某些过滤器映射到这些URL上。与映射到URL上相反,可以将这些过滤器映射到一个或多个Servlet名称上。

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>

在声明了过滤器之后,可以将它映射到任意数目的URL或Servlet名称。当然过滤器URL映射还可以包含通配符。

2.使用注解声明和映射过滤器

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

但是不可以对对过滤器链上的过滤器进行排序

三、过滤器排序

过滤器的顺序决定了过滤器在过滤器链中出现的位置,这里将会使用部署描述符来进行配置,因为注解无法进行排序配置。

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的实例:

这是处理中的第一个过滤器,它将记录处理请求的时间,并记录所有访问应用程序的请求信息——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() { }
}

Java Web高级编程(三)的更多相关文章

  1. Java Web高级编程(二)

    使用会话维持状态 一.会话 为了实现关联同一个用户端的多个请求和这些请求之间数据的共享,需要用到会话,会话用于维持请求和请求之间的状态.从服务器的角度,当用户的Web浏览器打开第一个链接到服务器的套接 ...

  2. Java Web高级编程(一)

    Servlet 一.创建Servlet类 在Java EE中,Servlet用来接收和响应终端用户的请求.Servlet是所有Web应用程序的核心类,是唯一既可以直接处理和响应用户请求,也可以将处理工 ...

  3. Java Web高级编程(四)

    WebSocket 一.WebSocket的产生 用户希望Web页面可以进行交互,用于解决这个问题的技术是JavaScript,现在Web上有许多的可用的JavaScript框架,在使用极少的Java ...

  4. java web高级编程 笔记1

    chapter1:了解web应用程序 web应用程序主要组件: Servlet 过滤器 监听器 JSP chapter2:各类web容器介绍 略 chapter3:Servlet介绍 Servlet是 ...

  5. Java Web高性能开发(三)

    今日要闻: Clarifai:可识别视频中物体 最近几年,得益于深度学习技术的发展,谷歌和Facebook等企业的研究人员在图形识别软件领域取得了重大突破.现在,一家名为Clarifai的创业公司则提 ...

  6. C++面向对象高级编程(三)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 一.拷贝构造 二.拷贝赋值 三.重写操作符 四.生命周期 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主 ...

  7. JavaEE-实验三 Java数据库高级编程

    该博客仅专为我的小伙伴提供参考而附加,没空加上代码具体解析,望各位谅解 1.在MySQL中运行以下脚本 CREATE DATABASE mydatabase; USE mydatabase; CREA ...

  8. java web学习总结(三十一) -------------------EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

  9. java web学习总结(三十) -------------------JSTL表达式

    一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...

随机推荐

  1. Web 动画帧率(FPS)计算

    我们知道,动画其实是由一帧一帧的图像构成的.有 Web 动画那么就会存在该动画在播放运行时的帧率.而帧率在不同设备不同情况下又是不一样的. 有的时候,一些复杂或者重要动画,我们需要实时监控它们的帧率, ...

  2. vue2入门之vue-cli

    vue-cli vue在web前端可谓是大放异彩,尤其在国内与angular.react有三足鼎立之势.很多人想入门vue2而又苦于不知从何下手.因为vue2是以组件化开发的,最好要搭配webpack ...

  3. java学习笔记之StringBuilder

    StringBuilder总结 StringBuilder概述: StringBuilder是一个线程不安全的类,他在字符串连接方面性能尤其出色 StringBuilder类的构造方法: 1.空参数构 ...

  4. Scheme -- Hierarchical Structures

    Question: produce a deep-reverse procedure that takes a list as argument  and returns as its value t ...

  5. JavaScript面向对象编程(9)高速构建继承关系之整合原型链

    前面我们铺垫了非常多细节.是为了让大家更加明晰prototype的使用细节: 如今能够将前面的知识整合起来,写一个函数用于高速构建基于原型链的继承关系了: function extend(Child, ...

  6. STM32W108无线射频模块通用IO接口应用实例

    STM32W108无线射频模块通用IO接口应用实例 本实例编写STM32W108的GPIO測试程序,通过控制GPIO引脚,实现对LED灯的控制. 开发环境与硬件说明 硬件:STM32W108无线开发板 ...

  7. poj 1860 Currency Exchange (SPFA、正权回路 bellman-ford)

    链接:poj 1860 题意:给定n中货币.以及它们之间的税率.A货币转化为B货币的公式为 B=(V-Cab)*Rab,当中V为A的货币量, 求货币S通过若干此转换,再转换为原本的货币时是否会添加 分 ...

  8. ElasticSearch和ElasticSearch Head环境搭建和数据模拟

    首先elasticsearch-6.0.0\bin目录下运行elasticsearch服务 修改elasticsearch-6.0.0\elasticsearch.yml文件 在文件最后加入下面代码, ...

  9. 大数据学习(6)MapReduce应用

    倒排索引 /** * * * <pre> *file1.txt: *hello ketty *hello tomcat * *file2.txt: *hello hadoop * *map ...

  10. 如何连接别人电脑上的Oracle数据库--duende99

    需要一些前提条件: 1.对方的主机能被连接(如在同一局域网内) 2.需要知道对方数据库IP.端口号.服务名 3.需要知道对方提供的管理数据库的用户名及密码 连接方法: 1.在本地的oracle安装目录 ...