Java Web高级编程(三)
使用过滤器改进应用程序
一、过滤器的目的
过滤器是可以拦截访问资源的请求、资源的响应或者同时拦截两者的应用组件。过滤器可以检测和修改请求和响应,同时也可以拒绝、重定向或转发请求。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高级编程(三)的更多相关文章
- Java Web高级编程(二)
使用会话维持状态 一.会话 为了实现关联同一个用户端的多个请求和这些请求之间数据的共享,需要用到会话,会话用于维持请求和请求之间的状态.从服务器的角度,当用户的Web浏览器打开第一个链接到服务器的套接 ...
- Java Web高级编程(一)
Servlet 一.创建Servlet类 在Java EE中,Servlet用来接收和响应终端用户的请求.Servlet是所有Web应用程序的核心类,是唯一既可以直接处理和响应用户请求,也可以将处理工 ...
- Java Web高级编程(四)
WebSocket 一.WebSocket的产生 用户希望Web页面可以进行交互,用于解决这个问题的技术是JavaScript,现在Web上有许多的可用的JavaScript框架,在使用极少的Java ...
- java web高级编程 笔记1
chapter1:了解web应用程序 web应用程序主要组件: Servlet 过滤器 监听器 JSP chapter2:各类web容器介绍 略 chapter3:Servlet介绍 Servlet是 ...
- Java Web高性能开发(三)
今日要闻: Clarifai:可识别视频中物体 最近几年,得益于深度学习技术的发展,谷歌和Facebook等企业的研究人员在图形识别软件领域取得了重大突破.现在,一家名为Clarifai的创业公司则提 ...
- C++面向对象高级编程(三)基础篇
技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 一.拷贝构造 二.拷贝赋值 三.重写操作符 四.生命周期 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主 ...
- JavaEE-实验三 Java数据库高级编程
该博客仅专为我的小伙伴提供参考而附加,没空加上代码具体解析,望各位谅解 1.在MySQL中运行以下脚本 CREATE DATABASE mydatabase; USE mydatabase; CREA ...
- java web学习总结(三十一) -------------------EL表达式
一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...
- java web学习总结(三十) -------------------JSTL表达式
一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...
随机推荐
- 实战-CentOS6.8配置nfs服务
如题 #服务端:请自行配置yum源 命令操作:yum install nfs-utils rpcbind #配置文件编辑:vi /etc/exports /data 0.0.0.0 (rw,sync, ...
- Ubuntu Linux訪问小米手机存储卡
操作系统: 麒麟14.04 安装工具 sudo apt-get install mtpfs libfuse-dev libmad0-dev sudo mkdir /media/mtp 重新启动与使用 ...
- 自学Zabbix1.3-zabbix进程
默认情况下zabbix包含5个程序:zabbix_agentd.zabbix_get.zabbix_proxy.zabbix_sender.zabbix_server,另外一个zabbix_java_ ...
- es6+require混合开发,兼容es6 module,import,export之 加载css及公用date-main
大家好!上篇文章已经介绍了搭建文件夹,以及加载js文件.现在讲一下加载css ,以及对baseUrl的理解 1.对项目结构的认知 一个项目的结构是根据项目的架构来决定的,当然也可以做到更智能,但是意义 ...
- Bandit Wargame Level12 Writeup
Level Goal The password for the next level is stored in the file data.txt, which is a hexdump of a f ...
- 多线程day01
多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. 一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程 ...
- Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:repackage failed: Unable to find main class
异常 [INFO] --- spring-boot-maven-plugin:1.5.6.RELEASE:repackage (default) @ spring-boot-starter-log - ...
- 详解功能版本管理之使用eoLinker
先看一个对话: "这里,你改一下,这里返回一个object." "好...好......" "还有这里,返回个String." ...... ...
- 数据加密,android客户端和服务器端可共用
安卓中,不管是内网还是外网,数据的传输首要考虑就是安全问题,尤其是用户信息,以及各种密码等敏感信息. 所以说,对数据的加密是很有必要的,尤其是当下物联网蓬勃发展的今天,数据安全尤为重要. 数据加密的方 ...
- 【CSS3】背景
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...