2,思路分析
1.创建一个表单用于发表言论。
2.创建一个txt文件,其中存入非法字符。(方便以后对敏感词汇库进行扩展)
3.创建一个Filter,拦截请求。在init方法中将txt文件中的非法字符读取到内存中。
4.获取请求中的参数,对请求的参数进ms行非法字符的校验。
5.如果言论中不含有非法字符,就放行。
6.如果言论中含有非法字符,就拦截,并且提示用户非法言论。
3,代码实现
WordFilter
package com.itheima.filter.k_demo敏感词汇;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
//由于这个过滤器仅仅是针对发表内容的过滤,所以它的映射路径只要捕获发表的servlet即可
@WebFilter("/publish")
public class WordFilter implements Filter {
//准备装敏感词汇的容器
List<String> wordlist = new ArrayList<>();
//只会执行一次
@Override
public void init(FilterConfig filterConfig) throws ServletException {
try {
System.out.println("敏感词汇过滤器::init~!");
//读取文件,得到每一个词汇,然后装到容器中。
//a. 要一行一行的读取。BufferedReader , readLine()
//b. 需要一个参数,reader
//c. 目前只有一个文件 IllegalWords.txt ---> 输入流
//d. 可以借助一个转换器 inputstreamreader(inputstream) 转换得到reader对象
//读取文件,转换成输入流,一般在web项目里面不建议使用new FileInputStream的写法
String path = filterConfig.getServletContext().getRealPath("");
//System.out.println("path=" + path);
InputStream is = filterConfig.getServletContext().getResourceAsStream("IllegalWords.txt");
System.out.println("is==" + is);
//把输入流转化成一个包装的reader对象,主要是为了方便读取每一行,因为一行就是一个敏感词汇
BufferedReader reader = new BufferedReader(new InputStreamReader(is , "utf-8"));
String line ;
//循环的读取每一行,读取到的每一行都赋值给上面的line对象。如果读到的是null 表示读到末尾了。
while( (line = reader.readLine()) != null){
System.out.println("line==" + line);
wordlist.add(line);
}
reader.close();/**/
} catch (Exception e) {
e.printStackTrace();
}
}
//会执行很多次,拦截到多少次请求,就执行多少次
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("敏感词汇过滤器::doFilter~!");
//1. 对发表的内容进行检查
// a. 知道发表的是什么内容
String message = servletRequest.getParameter("message");
// b. 读文件,获取到敏感词汇库,校验发表的内容是否含有敏感词汇。
for( String word : wordlist){
//判定发表的消息是否有敏感词汇
if(message .contains(word)){
//2. 如果有敏感词汇, 让敏感词汇变成*
message = message.replace(word , "***");
}
}
//3. 把这个修改好的内容存储到作用域中
servletRequest.setAttribute("msg", message);
//4. 放行,让请求到达servlet,以便内容能够发表出来
filterChain.doFilter(servletRequest ,servletResponse);
}
@Override
public void destroy() {
System.out.println("敏感词汇过滤器::destroy~!");
}
}
PublishServlet
package com.itheima.filter.k_demo敏感词汇;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/publish")
public class ServletDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取到要发表的言论
//String message = req.getParameter("message");
String message = (String)req.getAttribute("msg");
//2. 直接写到页面上: 您发布的内容是: xxxx
resp.getWriter().write("您发布的内容是:"+ message);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req ,resp);
}
}
4.小结
- 思路
- init()
- 读取非法字符文件, 把非法字符串存到List 【只需要读取一次, init()就执行一次】
- doFilter()方法
- 强转两个参数
- 获得用户发布的言论
- 遍历List集合, 判断用户发布的言论里面是否包含非法字符
- 如果包含, 拦截, 响应 ‘发布的言论包含非法字符,重新发布’
- 不包含, 放行
- 注意事项
- 读取非法字符文件 指定utf-8