Filter:过滤器

步骤:

  • 1.定义一个类,实现Filter
  • 2.复写方法
  • 3.配置拦截路径
web.xml的配置
1
2
3
4
5
6
7
8
<filter>
<filter-name>demo1</filter-name>
<filter-class>cn.filter.demo1</filter-class>
</filter>
<filter-mapping>
<filter-name>demo1</filter-name>
<url-pattern>/*</url-pattern>//拦截路径
</filter-mapping>

过滤器的生命周期

  • 1.init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次用于加载资源
  • 2.doFilter:每次拦截资源时被执行,执行很多次。
  • 3.destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。执行一次,用于释放资源。

拦截路径的配置

  • 1.具体的资源路径:/index.jsp 只有访问index.jsp资源时,过滤器才会被执行
  • 2.目录拦截: /user/* 访问/user下的所有资源时,过滤器都会被执行
  • 3.后缀名拦截: *.jsp 访问所有后缀名为jsp的资源时,过滤器都会被执行
  • 4.拦截所有资源: /* 访问所有资源时,过滤器都会被执行

拦截方式的配置

注解配置:
    1.REQUEST:默认值 浏览器直接请求资源
    2.FORWARD:转发访问资源
    3.INCLUDE:包含访问资源
    4.ERROR:错误跳转
    5.ASYNC:异步访问资源 

过滤器先后顺序问题

1.注解配置:按照类名的字符串比较规则比较,值小的先执行
2.web.xml配置:<filter-mappping>谁定义在前面,谁先执行

登录案例

判断是否登录
分析
1.判断是否是登录的相关资源
* 是 直接放行
* 不是 判断是否登录
2.判断当前用户是否登录,判断Session是否有user
* 有  已经登录  放行
* 没有  没有登录   跳转到登录页面
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package cn.test.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
* 登录验证的过滤器
*/
@WebFilter("/*")
public class loginFilter implements Filter {
public void destroy() {
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//0.强制转换
HttpServletRequest request = (HttpServletRequest) req;

//1.获取请求资源的路径
String uri = request.getRequestURI();

//2.判断是否包含登录相关的路径
if (uri.contains("/login.jsp") || uri.contains("/loginServlet") || uri.contains("/checkcodeServlet") || uri.contains("/js/")){
//放行
chain.doFilter(req, resp);
}else {
//不包含 需要验证用户是否登录
//从Session获取user
Object user = request.getSession().getAttribute("user");
if (user!=null){
//登录了 放行
chain.doFilter(req, resp);
}else {
//没有登录 跳转登录页面
request.setAttribute("login_msg","您尚未登录,请登录");
request.getRequestDispatcher("/login.jsp").forward(request,resp);
}
}

}

public void init(FilterConfig config) throws ServletException {

}

}

敏感词汇过滤

分析
1.对request对象进行增强。增强获取参数相关方法
2.放行。爨地代理对象
增强对象的功能
设计模式:一些通用的解决固定问题的方式
* 1.装饰模式
* 2.代理模式

实现步骤:
    - 1.代理对象和真实对象实现相同的接口
    - 2.代理对象  =  Proxy.newProxyInstance();
    - 3.使用代理对象调用方法
    - 4.增强方法 
增强方式:
    - 1.增强参数列表
    - 2.增强返回值类型
    - 3.增强方法体执行逻辑
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package cn.test.web.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;

/**
* 敏感词汇过滤器
*/
@WebFilter("/*")
public class sensitiveWordsFilter implements Filter {
public void destroy() {
}

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//创建代理对象,增强getParameter方法
ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//判断是否是getParameter
if (method.getName().equals("getParameter")){
//增强返回值
//获取返回值
String value = (String) method.invoke(req,args);
if (value != null){
for (String str:list){
if (value.contains(str)){
value = value.replaceAll(str,"***");
}
}
}
return value;
}
//判断是否是getParameterMap
if (method.getName().equals("getParameterMap")){
//由request得到的原数组不可改变,他是被锁住的,所以这里创建一个新数组来复制原数组,返回新的数组
//其实想法很想简单,既然传递进来的映射不可改变,那么自己new一个出来不就行了
Map<String,String[]> map1 = new HashMap<>();
Map<String,String[]> map = (Map<String, String[]>) method.invoke(req,args);
Set<String> keySet = map.keySet();

if (keySet != null){
for (String str:list){
for (String key:keySet){
String[] values = map.get(key);
for (int i=0;i<values.length;i++){
String value = values[i];
if (value.contains(str)){
value = value.replaceAll(str,"***");
values[i] = value;
}
}map1.put(key,values);
}
}
}
return map1;
}
return method.invoke(req,args);
}
});

//放行
chain.doFilter(proxy_req, resp);
}
private List<String> list = new ArrayList<String>();//敏感词汇
public void init(FilterConfig config) throws ServletException {
try {
//获取文件真实路径
ServletContext context = config.getServletContext();
String realPath = context.getRealPath("/WEB-INF/classes/敏感词汇.txt");

//读取文件
BufferedReader br = new BufferedReader(new FileReader(realPath));

//将文件的每一行数据添加到list集合中
String line = null;
while ((line=br.readLine())!=null){
list.add(line);
}

br.close();//释放资源
System.out.println(list);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

}

评论