[原创]java WEB学习笔记45:自定义HttpFilter类,理解多个Filter 代码的执行顺序,Filterdemo:禁用浏览器缓存的Filter,字符编码的Filter,检查用户是否登陆过的Filter
本博客为原创:综合 尚硅谷(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: jason_zhangz@163.com
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)都要采取可配置的方式