使用过滤器改进应用程序

一、过滤器的目的

过滤器是可以拦截访问资源的请求、资源的响应或者同时拦截两者的应用组件。过滤器可以检测和修改请求和响应,同时也可以拒绝、重定向或转发请求。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. python中csv文件的读取问题

    在python读取csv格式的文件时,使用csv.reader读取文件对象,出现了line contains NULL byte的错误,如下: reader = csv.reader(open(fil ...

  2. 网页设计——6.html其他标签

    今天学习html的其他标签: 一.列表 1.无序列表ul 基本结构: <ul  type="属性值"> <li>列表内容</li> </u ...

  3. [置顶] Java WebService接口生成和调用 图文详解

    webservice简介: Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据Web Service规范实施的应用之间 ...

  4. 选择客栈noip2011

    哈,没想到吧.今天居然有两篇(算什么,厕所读物吗 选择客栈 本题的更优解请跳转zt 这题11年,刚改2day. 对于30% 的数据,有 n ≤100: 对于50% 的数据,有 n ≤1,000: 对于 ...

  5. 浅谈 Integer 类

    在讲解 Integer 之前,我们先看下面这段代码: public static void main(String[] args) { Integer i = 10; Integer j = 10; ...

  6. java的热部署和热加载

    ps:热部署和热加载其实是两个类似但不同的概念,之前理解不深,so,这篇文章重构了下. 一.热部署与热加载 在应用运行的时升级软件,无需重新启动的方式有两种,热部署和热加载. 对于Java应用程序来说 ...

  7. python3 爬虫---爬取糗事百科

    这次爬取的网站是糗事百科,网址是:http://www.qiushibaike.com/hot/page/1 分析网址,参数''指的是页数,第二页就是'/page/2',以此类推... 一.分析网页 ...

  8. inline-block解决

    一.现象描述 真正意义上的inline-block水平呈现的元素间,换行显示或空格分隔的情况下会有间距 二.方法之移除空格 元素间留白间距出现的原因就是标签段之间的空格,因此,去掉HTML中的空格,自 ...

  9. 你为什么还坚持.NET

    C#换什么比较合适? 从TIOBE来看,Java.C++.C.Python都好,对了,还不能忘了JS. Sql Server换什么比较合适? MySql挺好,Oracle也不错,也还有不少选择. 都挺 ...

  10. Tomcat在Linux服务器上的BIO、NIO、APR模式设置

    一.BIO.NIO.AIO 先了解四个概念: 同步 : 自己亲自出马持银行卡到银行取钱(使用同步IO时,Java自己处理IO读写). 异步 : 委托一小弟拿银行卡到银行取钱,然后给你(使用异步IO时, ...