本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用
内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。
本人互联网技术爱好者,互联网技术发烧友
微博:伊直都在0221
QQ:951226918
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.为了方便使用,我们自定义处理 Http 的 HttpFilter
1 package com.jason.filter; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 import com.sun.org.apache.xml.internal.security.Init; 15 16 17 18 /** 19 * 20 * @ClassName:HttpFilter 21 * @Description:TODO 22 * @author: [email protected] 23 * @date:2016年7月13日下午10:50:00 24 * 25 * 26 */ 27 public abstract class HttpFilter implements Filter { 28 29 /** 30 * 用于保存FilterConfig 对象 31 */ 32 private FilterConfig filterConfig; 33 34 /** 35 * 不建议直接覆盖,若直接覆盖,将导致FilterConfig 成员变量初始化失败 36 */ 37 38 @Override 39 public void init(FilterConfig filterConfig) throws ServletException { 40 this.filterConfig = filterConfig; 41 init(); 42 } 43 44 /** 45 * @description:提供继承的初始化方式,可以通过getFilterConfig() 获取FilterConfig 对象 46 */ 47 protected void init() { 48 49 } 50 51 /** 52 * 53 * @Title: getFilterConfig 54 * @Description: 直接返回init(FilterConfig)的 FilterConfig 对象 55 * @param @return 56 * @return FilterConfig 57 * @throws 58 */ 59 public FilterConfig getFilterConfig() { 60 return filterConfig; 61 } 62 63 /** 64 * 原生的doFilter 方法,在方法内把ServletRequest,ServletResponse 转化为 HttpServletRequest HttpServletResponse,并且调用了doFilter()方式 65 * 若编写Filter 的过滤方法不建议直接继承该方法,而是继承 66 * doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) 67 */ 68 69 @Override 70 public void doFilter(ServletRequest req, ServletResponse res, 71 FilterChain chain) throws IOException, ServletException { 72 HttpServletRequest request = (HttpServletRequest) req; 73 HttpServletResponse response = (HttpServletResponse) res; 74 doFilter(request, response, chain); 75 76 } 77 /** 78 * 79 * @param request 80 * @param response 81 * @param filterChain 82 * @description: 抽象方法,为Http 请求必须实现的方法 83 */ 84 85 public abstract void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain); 86 87 /** 88 * 空的destroy 方法 89 */ 90 91 @Override 92 public void destroy() { 93 // TODO Auto-generated method stub 94 95 } 96 97 }
2.多个Filter 执行的顺序
3.demo1:使浏览器不缓存页面的过滤器
有 3 个 HTTP 响应头字段都可以禁止浏览器缓存当前页面,它们在 Servlet 中的示例代码如下:
response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
注意:并不是所有的浏览器都能完全支持上面的三个响应头,因此最好是同时使用上面的三个响应头
1 package com.jason.filter; 2 3 import java.io.IOException; 4 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.annotation.WebFilter; 12 import javax.servlet.http.HttpServletRequest; 13 import javax.servlet.http.HttpServletResponse; 14 15 /** 16 * Servlet Filter implementation class NoCacheFilter 17 */ 18 @WebFilter("/cache/*") 19 public class NoCacheFilter extends HttpFilter{ 20 21 @Override 22 public void doFilter(HttpServletRequest request, 23 HttpServletResponse response, FilterChain filterChain) { 24 25 response.setDateHeader("Expires",-1); 26 response.setHeader("Cache-Control","no-cache"); 27 response.setHeader("Pragma","no-cache"); 28 29 try { 30 filterChain.doFilter(request, response); 31 } catch (IOException e) { 32 // TODO Auto-generated catch block 33 e.printStackTrace(); 34 } catch (ServletException e) { 35 // TODO Auto-generated catch block 36 e.printStackTrace(); 37 } 38 39 } 40 41 42 }
4.demo2:字符编码过滤器 。即,所有的链接都得通过字符编码过滤器进行字符编码
1.在 web.xml 文件中配置初始化参数 encoding
1 <context-param> 2 <param-name>encoding</param-name> 3 <param-value>UTF-8</param-value> 4 </context-param> 5 <filter>
2.创建一个Filter 继承 HttpFilter 且 映射到所有访问路径
1 package com.jason.filter; 2 3 import java.io.IOException; 4 import java.io.UnsupportedEncodingException; 5 6 import javax.servlet.Filter; 7 import javax.servlet.FilterChain; 8 import javax.servlet.FilterConfig; 9 import javax.servlet.ServletException; 10 import javax.servlet.ServletRequest; 11 import javax.servlet.ServletResponse; 12 import javax.servlet.annotation.WebFilter; 13 import javax.servlet.http.HttpServletRequest; 14 import javax.servlet.http.HttpServletResponse; 15 16 /** 17 * Servlet Filter implementation class EncodingFilter 18 */ 19 @WebFilter("/*") 20 public class EncodingFilter extends HttpFilter { 21 22 private String encoding; 23 24 @Override 25 protected void init() { 26 encoding = getFilterConfig().getServletContext().getInitParameter("encoding"); 27 } 28 29 @Override 30 public void doFilter(HttpServletRequest request, 31 HttpServletResponse response, FilterChain filterChain) { 32 33 try { 34 request.setCharacterEncoding(encoding); 35 filterChain.doFilter(request, response); 36 } catch (Exception e) { 37 e.printStackTrace(); 38 } 39 } 40 41 }
5.demo3:检查用户是否登录过的过滤器
1) 情景:系统中的某些页面只有在正常登陆后才可以使用,用户请求这些页面时要检查 session 中有无该用户信息,但在所有必要的页面加上session的判断相当麻烦的事情
2) 解决方案:编写一个用于检测用户是否登陆的过滤器,如果用户未登录,则重定向到指的登录页面
3) 要求:需检查的在 Session 中保存的关键字; 如果用户未登录,需重定向到指定的页面(URL不包括 ContextPath); 不做检查的URL列表(以分号分开,并且 URL 中不包括 ContextPath)都要采取可配置的方式