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方法将数据写到临时容器中
  • 相关阅读:
    eclipse中的Invalid text string (xxx).
    在jsp文件中出现Unknown tag (c:out)
    eclipse 界面复原
    ecilpse 纠错插件
    Multiple annotations found at this line:- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
    Port 8080 required by Tomcat v9.0 Server at localhost is already in use. The server may already be running in another process, or a system process may be using the port.
    调用第三方https接口
    调用第三方http接口
    创建带值枚举
    spring整合redis之Redis配置文件
  • 原文地址:https://www.cnblogs.com/codingpark/p/4276235.html
Copyright © 2011-2022 走看看