zoukankan      html  css  js  c++  java
  • JavaWeb之Filter快速入门(十七)

    Filter

    1. 过滤器简介

    1. 过滤器是Java Web三大组件之一,它在很多方面都与Servlet相似
    2. 过滤器可以理解成拦截器,其实过滤器的代码是环绕在被访问资源的前后,为被访问的资源提供增强的作用(比如过滤器就像楼层中保安,所有人员经过楼层必须经过保安)
    3. 过滤器的应用场景:
    	1). 执行目标资源之前做预处理工作,例如设置编码,这种试通常都会放行,只是在目标资源执行之前做一些准备工作
    	2). 通过条件判断是否放行,例如校验当前用户是否已经登录,或者用户IP是否已经被禁用
    	3). 在目标资源执行后,做一些后续的特殊处理工作,例如把目标资源输出的数据进行处理

    2. 过滤器编写步骤

    1. 编写一个类实现javax.servlet.Filter接口。在doFilter方法中编写过滤代码
    2. 在web.xml中配置哪些资源要经过该过滤器
    	<filter>
    		<filter-name>命名</filter-name>
    		<filter-class>包名.类名</filter-class>
    	</filter>
    	<filter-mapping>
    		<filter-name>命名</filter-name>
    		<url-pattern>拦截的资源</url-pattern>
    	</filter-mapping>
    
    一个目标资源可以指定多个过滤器,过滤器的执行顺序是在web.xml文件中的</filter-mapping>部署顺序

    3. 过滤器的执行过程和生命周期

    1、过滤器是在应用启动时就完成了实例化和初始化
    2、对于过滤范围内资源的每次访问都会调用doFilter
    3、应用被卸载时会调用destory方法

    4. FilterConfig&FilterChain

    ServletConfig
    	ServletContext getServletContext():获取ServletContext的方法;
    	String getFilterName():获取Filter的配置名称;与<filter-name>元素对应;
    	String getInitParameter(String name):获取Filter的初始化配置,与<init-param>元素对应;
    	Enumeration getInitParameterNames():获取所有初始化参数的名称
    FilterChain
    	doFilter()方法的参数中有一个类型为FilterChain的参数,它只有一个方法:doFilter(ServletRequest,ServletResponse)
    区别:
    	1.个数不同  
    		Filter接口doFilter是3个参数:			ServletRequest,ServletResponse,FilterChain
    		FilterChian的doFilter是2个参数:			ServletRequest,ServletResponse
    	2.作用不同
    		Filter接口doFilter拦截作用
    		FilterChian中doFilter起放行作用

    5. 过滤器其他配置

    过滤四个类型:REQUEST FORWARD INCLUDE  ERROR
    <filter-mapping>
        <filter-name>Filter06_Typetest</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>	<!-- 默认REQUEST,如果配置了其他类型,默认的就没有了 -->
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    6. 巩固包装设计模式

    1、装饰模式口诀
    	a、定义一个类实现与被包装类相同的接口
    	b、定义一个变量记住被包装类对象的引用
    	c、定义构造方法,传入被包装类对象的实例
    	d、对于要改写的方法,改写即可
    	e、对于不需要改写的方法,调用被包装对象的对应方法
    2、装饰模式变化
    	改写的方法所在的类,本身就是个包装类
    	a、定义一个类,继承要包装的类
    	b、定义一个变量,记住被包装类的引用
    	c、定义构造方法,传入被包装类的实例
    	d、覆盖要改写的方法

    过滤器的案例

    1. 过滤器简单案例(编码/静态和动态缓存控制)

    1. 过滤器中实现设置编码
    	强转request和response
    	强转request和response、初始化容器时赋值config属性
    	String encoding = config.getInitParameter("encoding");
    	request.setCharacterEncoding(encoding);
    	response.setContentType("text/html;charset="+encoding);
    	chain.doFilter(request, response);
    
    2. 全站动态资源无缓存
    	强转request和response
    	response.setHeader("Expires", "0");
    	response.setHeader("Cache-Control", "no-cache");
    	response.setHeader("pragma", "no-cache");
    	chain.doFilter(request, response);
    
    3. 静态资源设置缓存时间
    	强转request和response
    	String uri = request.getRequestURI();
    	String extendsionName = uri.substring(uri.lastIndexOf(".")+1);
    	
    	String time = "0";
    	time = config.getInitParameter(extendsionName);
    	request.setCharacterEncoding("UTF-8");
    	response.setContentType("text/html;charset=UTF-8");
    	
    	if(time != null) {
    		response.setDateHeader("Expires", System.currentTimeMillis()+Integer.parseInt(time)*60*60*1000);
    	}
    	
    	chain.doFilter(request, response);
    
    最后勿忘配置web.xml文件

    2. 用户自动登录

    用户自动登录案例
    1. 新建数据库中的表和对应的JavaBean对象
    	create database day19;
    	use day19;
    	create table user(
    		id int primary key,
    		username varchar(100) not null unique,
    		password varchar(100) not null
    	);
    	
    	private int id;
    	private String username;
    	private String password;
    2. 数据访问层UserDaoImpl类
    	void save(User user)
    	User find(String username, String password)
    3. 工具类
    	引入DBUtils/C3P0Util/EncodingUtil工具类
    4. 业务逻辑层BusinessServiceImpl类
    	public void register(User user)
    	public User findUser(String username, String password)
    5. LoginServlet类
    	过滤器解决乱码问题
    	5.1 获取请求参数
    	5.2 调用业务逻辑判断是否登录成功
    	5.3 将用户名和密码设置在cookie信息中Cookie c = new Cookie("loginInfo",loginInfo);
    	5.4 判断用户选择的方式,设置相应的有效期
    	5.5 设置cookie路径
    	5.6 将cookie添加到响应头中
    	5.7 重定向到首页
    	
    6. LogoutServlet类
    	6.1 移除session域中的user
    	6.2 新建空的cookie信息,设置cookie的有效期为过期0,设置cookie路径,添加到response头信息中
    	6.3 重定向到首页
    
    7. 过滤器类,处理编码
    	7.1 获取初始化的参数
    	7.2 设置编码之后再放行
    	
    8. 自动登录过滤器类AutoLoginFilter
    	8.1 强制request,response
    	8.2 获取请求的uri信息
    	8.3 如果请求的参数不是以login.jsp登录
    	8.4 获取session域中的user
    	8.5 如果user为空
    	8.6 获取请求的cookie信息
    	8.7 如果获取的cookie为空重定向登录页面
    	8.8 遍历所有cookie,如果为是用户的cookie就赋值为新cookie,break;
    	8.9 如果赋值的新cookie不为空,获取cookie中的值
    	8.10 切割value获取username和password中的值
    	8.11 解码用户名,调用业务逻辑层方法判断用户名和密码
    	8.12 如果获得的用户名不为空,将用户设置到session域中
    	8.13 chain放行
    	
    	
    页面设计
    	1. login.jsp	用户登录页面提供选择有效期,提交到LoginServlet类
    	2. top.jsp		头部,如果session域中的用户为空,提示登录,如果不为空,提示欢迎界面,提供注销功能
    	3. index.jsp	引入top.jsp,提供帖子链接
    	4. 1.jsp 		帖子链接

    3. 过滤器拓展案例(全站编码/敏感词汇/html标签过滤)

    1. 全站编码问题
    	1). 强转request/response
    	2). 设置编码为了解决post编码问题
    	3). 若解决get提交编码问题,在doFilter放行之前包装一下request对象
    	4). 定义MyHttpServletRequest继承HttpServletRequestWrapper
    	5). 重写getParameter方法
    		super.getParameter(name);接收用户请求的的参数的值
    		如果为空直接返回null
    		判断请求的方式super.getMethod(),如果get请求,将请求的值编码再解码
    		
    2. 敏感词汇过滤
    	1). 强转request/response
    	2). 在doFilter放行之前包装一下request对象
    	3). 定义MyHttpServletRequest继承HttpServletRequestWrapper
    	4). 定义词库词汇
    	5). 获取请求参数的值,如果为空,直接返回空
    	6). 遍历词库,替换请求参数的值
    	7). 最后返回请求参数的值
    	
    3. HTML标签过滤
    	1). 强转request/response
    	2). 在doFilter放行之前包装一下request对象
    	3). 定义MyHtmlServletRequest继承HttpServletRequestWrapper
    	4). 调用filter方法替换请求参数的值
    	5). filter方法在tomcatwebappsexamplesWEB-INFclassesutilHTMLFilter.java

    4. 全站压缩

    1. 建立GZIP压缩过滤类GzipFilter
    2. 在放行之前改写response,然后把改写之后的response传给doFilter
    3. 针对HttpServletResponseWrapper,改写类为MyHttpServletResponse,重写其中的getOutputStream和getWriter方法
    	3.1 定义临时容器
    	3.2 定义获取临时容器的数据getBufferByte()
    6. 针对临时容器,实现HttpServletResponseWrapper,提供write方法将数据写到临时容器中
  • 相关阅读:
    自己用的vim插件
    关于利用python进行验证码识别的一些想法
    看看黑客如何破解验证码机制
    不懂技术的人不要对懂技术的人说这很容易实现
    4个mysql客户端工具的比较
    GB2312,GBK和UTF-8的区别
    Windows下用Python你会几种copy文件的方法?
    python3.4连接mysql数据库的方法
    python3操作mysql教程
    python win32com
  • 原文地址:https://www.cnblogs.com/codingpark/p/4276235.html
Copyright © 2011-2022 走看看