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乱码过滤器和响应压缩过滤器 ------------ 理解实现过程 ,保存起来会使用
客户信息系统增删改查必备
掌握分页查询原理
|
|