博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Filter过滤器
阅读量:7173 次
发布时间:2019-06-29

本文共 6577 字,大约阅读时间需要 21 分钟。

hot3.png

过滤器快速入门

Filter也称之为过滤器

通过它可以对web服务器管理的所有web资源进行拦截,从而实现特殊控制功能.例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能

173120_moou_3669094.png

173143_lPvD_3669094.png

FilterChain

  • 在一个web工程中,对同一个web资源进行多个过滤器拦截,多个过滤器在tomcat服务器加载时,组成过滤器链FilterChain。

  • 当使用多个Filter后,每个Filter都必须执行filterChain.doFilter()方法才能使目标资源执行

Filter的生命周期和FilterConfig的使用

 

生命周期方法

  • init(FilterConfig) : 在web服务器启动时,Filter对象会被创建,init方法执行.Filter对象只有一个,init方法只会被执行一次

    • 和Servlet不同,Servlet默认情况下,在第一次访问时创建对象初始化

  • doFilter(ServletRequest,ServletResponse) : 在每一次请求时,只要拦截目标资源,都会执行

  • destroy() 在服务器正常关闭、重启时调用

FilterConfig (ServletConfig) : 为过滤器提供初始化参数、通过config获得ServletContext

  • getInitParameter(java.lang.String name) : 获得初始化参数

  • getServletContext() : 获得ServletContext 对象

映射配置注意事项

  • 如何决定过滤器执行顺序

    • 过滤器先后执行的顺序取决于filter-mapping标签的顺序.

    • 如果使用的是注解,执行的顺序是类名的字母排列顺序

  • 配置过滤器进行过滤时,除了使用<url-pattern>之外,也可以使用<servlet-name>标签,但是对应的servlet也必须在web.xml中配置.

  • <dispatcher> 指定过滤器拦截目标资源的调用方式

    173518_cACV_3669094.png

    • 四种调用方式

      • REQUEST : 客户端请求过滤(实际开发中一般使用该默认方式)

      • FORWARD : 转发过滤

      • INCLUDE : 包含过滤

      • ERROR : 错误页面过滤 web.xml 配置error-page

      • 如果没有指定拦截模式,默认拦截REQUEST

173537_2QWH_3669094.png

 

案例配置全站编码集

Java增强方法的三种途径

  • 类继承 、方法覆盖

    • 必须控制对象创建,才能使用该方式

  • 装饰者模式

    • 必须和目标对象实现相同接口或继承相同父类,特殊构造器(传入被包装对象)

  • 动态代理

    • 根据原对象在内存中构造代理对象,原对象的所有方法,都将执行代理对象的invoke方法

// 在web.xml中指定
/*
, 拦截所有资源public class EncodingFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 强制类型转换 HttpServletRequest req = (HttpServletRequest) request; // 获取请求方式 String method = req.getMethod(); // 根据请求方式的不同,解决不同的乱码 if ("get".equalsIgnoreCase(method)) { MyRequest myRequest = new MyRequest(req); chain.doFilter(myRequest, response); } else if ("post".equalsIgnoreCase(method)) { // POST请求方式,处理乱码 req.setCharacterEncoding("utf-8"); chain.doFilter(request, response); } } public void init(FilterConfig fConfig) throws ServletException { }}// 装饰者模式解决get请求乱码class MyRequest extends HttpServletRequestWrapper { private HttpServletRequest req; public MyRequest(HttpServletRequest request) { super(request); this.req = request; } @Overridepublic String getParameter(String name) { if (name != null) { String[] st = (String[]) getParameterMap().get(name); if (st != null && st.length > 0) { return st[0]; } } return null;}@Overridepublic String[] getParameterValues(String name) { if (name != null) { return (String[]) getParameterMap().get(name); } return null;}private boolean flag = true;@Overridepublic Map getParameterMap() { // 1.得到原始的map集合 Map
map = request.getParameterMap();// 乱码 if (flag) { // 2.将map集合中的String[]得到,解决每一个元素的乱码问题. for (String key : map.keySet()) { String[] st = map.get(key); // 得到每一个数组 for (int i = 0; i < st.length; i++) { try { st[i] = new String(st[i].getBytes("iso8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } } flag = false; } return map;}}

 

案例自动登录

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%>
登录页面 ${msg }
用户名:
密码:
自动登录:

welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"	pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
Insert title here
您还没有登录,
去登陆
${user.username } 欢迎你

LoginServlet

protected void doGet(HttpServletRequest request,		HttpServletResponse response) throws ServletException, IOException {	// 获取用户输入的用户名和密码	String name = request.getParameter("username");	String psw = request.getParameter("password");	// 获取用户是否勾选了自动登录	String autologin = request.getParameter("autologin");	// 执行查询操作	QueryRunner queryRunner = new QueryRunner(JDBCUtils.getDataSource());	String sql = "select * from users where username = ? and password = ? ";	try {		User user = queryRunner.query(sql, new BeanHandler<>(User.class),				name, psw);		// 如果查询失败,说明登录的用户名或密码错误		if (user == null) {			request.setAttribute("msg", "用户名或密码错误");			request.getRequestDispatcher("/login.jsp").forward(request,					response);		} else { // 查询成功,说明登录成功			// 如果用户勾选了自动登录,把用户名和密码以cookie形式写回客户端,用于下次自动登录			if ("auto".equals(autologin)) {				Cookie usrCookie = new Cookie("username", name);				usrCookie.setPath("/");				usrCookie.setMaxAge(60 * 60 * 24 * 7);				Cookie pswCookie = new Cookie("password", psw);				pswCookie.setPath("/");				pswCookie.setMaxAge(60 * 60 * 24 * 7);				response.addCookie(usrCookie);				response.addCookie(pswCookie);			}			// 登录成功,把user对象存储到session中			request.getSession().setAttribute("user", user);			request.getRequestDispatcher("/welcome.jsp").forward(request,					response);		}	} catch (SQLException e) {		e.printStackTrace();	}}

AutoLoginFilter

public void doFilter(ServletRequest request, ServletResponse response,		FilterChain chain) throws IOException, ServletException {	// 当前用户没有登录,再登录	HttpServletRequest httpServletRequest = (HttpServletRequest) request;	// 从Request对象中获取user	User user = (User) httpServletRequest.getAttribute("user");	// 如果user对象为空,说明用户没有登录	if (user == null) {		// 没有登录,从Cookie中获取信息		String nameCookie = CookieUtils.findCookie(httpServletRequest,				"username");		String pswCookie = CookieUtils.findCookie(httpServletRequest,				"password");		// 如果两个cookie信息都存在,就登录		if (nameCookie != null && pswCookie != null) {			// 执行登录			QueryRunner queryRunner = new QueryRunner(					JDBCUtils.getDataSource());			String sql = "select * from users where username = ? and password = ? ";			try {				User loginUser = queryRunner.query(sql,						new BeanHandler<>(User.class), nameCookie,						pswCookie);				// 如果登录成功,将信息存入session				if (loginUser != null) {					httpServletRequest.setAttribute("user", loginUser);					chain.doFilter(request, response);				}			} catch (SQLException e) {				e.printStackTrace();			}		} else {			// 如果没有cookie信息,就放行			chain.doFilter(request, response);		}	} else {		System.out.println("user !== null");		// 如果已经登录,直接放行		chain.doFilter(request, response);	}}

案例禁用所有JSP页面的缓存

实现

  1. 在web.xml中指定<url-pattern>*.jsp</url-pattern>, 拦截所有jsp页面

  2. 过滤器代码

public void doFilter(ServletRequest request, ServletResponse response,		FilterChain chain) throws IOException, ServletException {	// 在实际开发中,我们为了能够实时显示页面,需要禁用缓存	// 但是如果在每个页面都手动的书写以下三行代码,会很繁琐	// 所以可以直接在filter中设置以下三行代码	// 设置前需要将ServletResponse类型的response进行类型转换	HttpServletResponse httpServletResponse = (HttpServletResponse) response;	httpServletResponse.setDateHeader("Expires", -1);	httpServletResponse.setHeader("Cache-Control", "no-cache");	httpServletResponse.setHeader("Pragma", "no-cache");	chain.doFilter(request, response);}

 

转载于:https://my.oschina.net/px828261/blog/1550964

你可能感兴趣的文章
ORACLE用SYS登录报ORA-28009:connection as SYS should be as SYSDBA OR SYSOPER解决方法
查看>>
foreach使用
查看>>
CubieBoard 简单入门
查看>>
NHibernate 集合映射基础(第四篇) - 一对一、 一对多、多对多小示例
查看>>
【oneday_onepage】—— 美国人的仪容整洁与个人卫生
查看>>
DIOCP开源项目-数据库连接池的使用<多帐套数据库>
查看>>
数据库设计的三范式
查看>>
PDO方法连接数据库(怕忘记,记起来)
查看>>
Gulan查询UI排布
查看>>
技术贴:asp.net实现唯一账户在线 禁止同一帐号同时在线 asp.net实现您的帐号在别处登录,您已被迫下线!...
查看>>
详解索引连接类型
查看>>
【剑道】用语中日对照
查看>>
UPNP
查看>>
.NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
查看>>
Salience Model
查看>>
是新浪移动云
查看>>
centos安装tomcat7
查看>>
php根据身份证号码计算年龄
查看>>
[转]关于position 的 static、relative、absolute、fixed、inherit
查看>>
[转]SSIS cannot convert between unicode and non-unicode string
查看>>