黑马程序员技术交流社区

标题: 关于过滤器的一些知识,有用的着的可以看看 [打印本页]

作者: cxc0603    时间: 2016-6-9 09:29
标题: 关于过滤器的一些知识,有用的着的可以看看
Servlet技术规范 描述三种技术 : Servlet(服务器小程序) 、Filter(过滤器) 、Listener(监听器)

Filter运行在服务器端,对服务器端web资源的访问 进行拦截,起到过滤的作用

Servlet API中 定义接口 Filter,用户只需要编写程序实现Filter接口,完成过滤器编写

Filter快速入门
1、编写类 实现 Filter接口
2、在服务器端注册 Filter (配置拦截哪个web资源) ----- web.xml
  <!-- 注册过滤器 -->
  <filter>
          <filter-name>Filter1</filter-name>
          <filter-class>cn.itcast.filter.Filter1</filter-class>
  </filter>       
  <!-- 配置过滤器去拦截哪个资源 -->
  <filter-mapping>
          <filter-name>Filter1</filter-name>
          <url-pattern>/hello.jsp</url-pattern>
  </filter-mapping>       

3、客户端访问被拦截目标资源之前,服务器调用Filter的doFilter方法 ,执行过滤
4、Filter的doFilter方法中传入 FilterChain, 如果调用FilterChain的doFilter 就会执行目标资源,否则目标资源不会执行
chain.doFilter(request, response);

FilterChain
在客户端访问服务器web资源时,服务器端为一个web资源,配置多个过滤器拦截 ,这多个过滤器,就会组成过滤器链 FilterChain, 调用FilterChain的doFilter 表示要执行过滤器链下一个资源,如果当前过滤器已经是链上最后一个过滤器,就会执行目标资源

* web服务器根据Filter在web.xml文件中的注册顺序<mapping>,决定先调用哪个Filter

Filter生命周期 init(FilterConfig) doFilter(request,response,filterChain) destroy()
1、Filter对象在tomcat服务器启动时 创建,调用init方法  (只会创建一个对象,init方法执行一次)
2、doFilter 每次拦截目标资源时,执行
3、destroy 服务器关闭时执行

FilterConfig 作用和 ServletConfig 类似,用来在Filter初始化阶段,将参数传递给过滤器
1、通过  String getInitParameter(String name)  获得过滤器初始化参数
2、通过 ServletContext getServletContext() 获得ServletContext对象
* FilterConfig 提供参数,是Filter类私有参数,Filter2的初始化参数,不能在Filter1 中进行获取
* 配置全局参数,<context-param> 进行配置,通过ServletContext 获得

<filter-mapping> 过滤器拦截配置
1、如果连接目标资源是一个Servlet,可以选择url和servlet名称两种配置方式
<!-- 拦截/hello是Servlet 路径 -->
<url-pattern>/hello</url-pattern>
<!-- 拦截Servlet 还可以通过Servlet 名称进行拦截 -->
<servlet-name>HelloServlet</servlet-name>
2、url-pattern 和 Servlet中路径写法一样,有三种 : 完全匹配、目录匹配、扩展名匹配
3、<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式
容器调用服务器端资源 有四种方式
REQUEST、FORWARD、INCLUDE、ERROR

=========================================================================================================================================
Filter应用

应用一:统一全站字符编码过滤器
案例:编写jsp 输入用户名,在Servlet中获取用户名,将用户名输出到浏览器上

处理请求post乱码代码
request.setCharacterEncoding("utf-8");
设置响应编码集代码
response.setContentType("text/html;charset=utf-8");

经常会使用,而过滤器可以在目标资源之前执行,将很多程序中处理乱码公共代码,提取到过滤器中 ,以后程序中不需要处理编码问题了

应用二:禁止浏览器缓存动态页面的过滤器
因为动态页面数据,是由程序生成的,所以如果有缓存,就会发生,客户端查看数据不是最新数据情况 ,对于动态程序生成页面,设置浏览器端禁止缓存页面内容

response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");

将禁用缓存代码,提起到过滤器中,通过url配置,禁用所有JSP页面的缓存

应用三:控制浏览器缓存静态web资源
Tomcat缓存策略

对于服务器端经常不变化文件,设置客户端缓存时间,在客户端资源缓存时间到期之前,就不会去访问服务器获取该资源 -------- 比tomcat内置缓存策略更优手段
* 减少服务器请求次数,提升性能

设置静态资源缓存时间,需要设置 Expires 过期时间 ,在客户端资源没有过期之前,不会产生对该资源的请求的
* 设置Expires 通常使用 response.setDateHeader 进行设置 设置毫秒值

===============================================================================================================================================
应用四:自动登陆过滤器
在访问一个站点,登陆时勾选自动登陆(三个月内不用登陆),操作系统后,关闭浏览器;过几天再次访问该站点时,直接进行登陆后状态

在数据库中创建 user表

create table user (
   id int primary key auto_increment,
   username varchar(20),
   password varchar(40),
   role varchar(10)
);

insert into user values(null,'admin','123','admin');
insert into user values(null,'aaa','123','user');
insert into user values(null,'bbb','123','user');

自动登陆 :未登录、存在自动登陆信息、自动登陆信息正确

在用户完成登陆后,勾选自动登陆复选框,服务器端将用户名和密码 以Cookie形式,保存在客户端 。当用户下次访问该站点,AutoLoginFilter 过滤器从Cookie中获取 自动登陆信息
1、判断用户是否已经登陆,如果已经登陆,没有自动登陆的必要
2、判断Cookie中是否含有自动登陆信息 ,如果没有,无法完成自动登陆
3、使用cookie用户名和密码 完成自动登陆

如果将用户密码保存在cookie文件中,非常不安全的 ,通常情况下密码需要加密后才能保存到客户端
* 使用md5算法对密码进行加密
* md5 加密算法是一个单向加密算法 ,支持明文---密文 不支持密文解密

MySQL数据库中提供md5 函数,可以完成md5 加密
mysql> select md5('123');
+----------------------------------+
| md5('123')                       |
+----------------------------------+
| 202cb962ac59075b964b07152d234b70 |
+----------------------------------+
解密后结果是32位数字 16进制表示

Java中提供类 MessageDigest 完成MD5加密

------------------------------------------------------------------
将数据表中所有密码 变为密文 update user set password = md5(password) ;
在Demo4Servlet 登陆逻辑中,对密码进行md5 加密
在AutoLoginFilter 因为从Cookie中获得就是加密后密码,所以登陆时无需再次加密


------------------------------------------------------------------
MD5 在2004 年被王小云破解,md5算法是多对一加密算法,出现两个加密后相同密文的明文很难发现 ,王小云并没有研究出md5 解密算法,研究出一种提高碰撞概率的算法

-------------------------------------------------------------------
应用五:过滤器实现URL级别权限认证
系统中存在很多资源,将需要进行权限控制的资源,放入特殊路径中,编写过滤器管理访问特殊路径的请求,如果没有相应身份和权限,控制无法访问

认证:who are you ? 用户身份的识别 ------------ 登陆功能
权限:以认证为基础 what can you do ? 您能做什么? 必须先登陆,才有身份,有了身份,才能确定可以执行哪些操作

=====================================================================================================================================================
Filter高级应用

Decorator模式
1、包装类需要和被包装对象 实现相同接口,或者继承相同父类
2、包装类需要持有 被包装对象的引用
在包装类中定义成员变量,通过包装类构造方法,传入被包装对象
3、在包装类中,可以控制原来那些方法需要加强
不需要加强 ,调用被包装对象的方法
需要加强,编写增强代码逻辑

ServletRequestWrapper 和 HttpServletRequestWrapper 提供对request对象进行包装的方法,但是默认情况下每个方法都是调用原来request对象的方法,也就是说包装类并没有对request进行增强

在这两个包装类基础上,继承HttpServletRequestWrapper ,覆盖需要增强的方法即可

应用六:完全解决get和post乱码的过滤器
在Filter中,对request对象进行包装,增强获得参数的方法
getParameter
getParameterValues
getParameterMap


ServletResponseWrapper 和 HttpServletResponseWrapper 提供了对response 对象包装,继承 HttpServletResponseWrapper ,覆盖需要增强response的方法

应用七:增强Response对象,对响应数据进行压缩
复习:Tomcat服务器内,提供对响应压缩 配置实现
在conf/server.xml 中
<Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"/> 添加 compressableMimeType 和 compression
没有压缩 :  00:00:00.000        0.063        7553        GET        200        text/html        http://localhost/

<Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" compressableMimeType="text/html,text/xml,text/plain" compression="on"/>

压缩后 :  00:00:00.000        0.171        2715        GET        200        text/html        http://localhost/
Content-Encoding: gzip
Content-Length : 2715

实际开发中,很多情况下,没有权限配置server.xml  ,无法通过tomcat配置开启gzip 压缩

编写过滤器对响应数据进行gzip压缩

flush 方法
只有没有缓冲区字节流,FileOutputStream 不需要flush
而字节数组ByteArrayOutputStream、字节包装流、字符流 需要flush ----- 这些流在调用close方法时都会自动flush

==================================================================================================================
过滤器
1、过滤器编写步骤  
2、全局编码、禁用缓存、设置过期时间 过滤器
3、自动登陆/URL级别权限控制 --- 必须掌握 *****
4、通用get/post乱码过滤器和响应压缩过滤器  ------------ 理解实现过程 ,保存起来会使用

客户信息系统增删改查必备
掌握分页查询原理



















































































作者: 坂田银时    时间: 2016-6-9 09:42
子类需要继承父类的泛型吗?




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2