使用Filter实现非法字符过滤
需求:用户在评论页面输入非法字符以后,需要将非法字符替换为*
需要考虑的问题
1.用户输入的非法字符可能会有很多种,如果想要校验用户输入的字符是否是非法字符,首先需要将非法字符存储起来,而不是写死,那么存储非法字符的存储位置
将非法字符存储到文件中,服务器启动之后就应该读取文件中的内容并且存储到集合中,而不是等到请求过来之后再读,因为这样会影响体验,
2.由于可能会有很多的页面存在用户输入的数据(订单评价,商品搜索等等),因此这个事情应该交给Filter去做,而不是servlet,因为servlet是负责处理没有非法字符的请求,有非法字符的请求统一交给Filter去做,这样就是实现了非法字符的过滤。
模拟评论页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>评论页面</title> </head> <body> <h1>评论页面处理非法字符</h1> <form action="${pageContext.request.contentType}/comments" method="post"> 评论内容:<input type="text" name="comments"><br> <input type="submit"> </form> </body> </html>
在src下创建非法字符的文件
过滤器处理非法字符
package 过滤器; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; @WebFilter("/comments") public class illegalCharcaterFilter implements Filter { List<String> list; @Override public void init(FilterConfig filterConfig) throws ServletException { //获取非法的字节输入流 InputStream resourceAsStream = illegalCharcaterFilter.class.getClassLoader().getResourceAsStream("illegal.txt"); InputStreamReader inputStreamReader = null; try { inputStreamReader = new InputStreamReader(resourceAsStream,"UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String line =null; list = new ArrayList<>(); while(true){ try { if (!((line=bufferedReader.readLine())!=null)) break; } catch (IOException e) { e.printStackTrace(); } list.add(line); } System.out.println("当前的非法字符"); for (String s:list){ System.out.println(s); } } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //进行非法字符的替换 //使用动态代理增强HttpServletRequest的getparameter()方法 HttpServletRequest req =(HttpServletRequest)servletRequest; HttpServletRequest proxyHttpServletRequest=(HttpServletRequest) Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(), new Class[]{HttpServletRequest.class}, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String returnValue=null; String proxyMethodName="getParameter"; //增强getParameter的方法 if(method.getName().equals(proxyMethodName)){ //目的是改变getParameter的返回值 //执行原本的方法获取返回值 returnValue=(String)method.invoke(req,args); //将返回值的结果替换为非法字符** if(returnValue!=null){ if(list!=null){ //遍历所有的非法字符 for (String illegalCharacter:list){ if(returnValue.contains(illegalCharacter)){ String asterisk=""; //用* 号代表一个字符 for (int i=0;i<illegalCharacter.length();i++){ asterisk+="*"; } //将非法字符替换成星号 returnValue=returnValue.replace(returnValue,asterisk); System.out.println("替换之后的为:"+returnValue); } } } return returnValue; } } //如果不是getParameter方法,则执行原来的方法,不增强 return method.invoke(req,args); } }); filterChain.doFilter(proxyHttpServletRequest,servletResponse); } @Override public void destroy() { } }
servlet处理请求
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("/comments") public class illegalServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); resp.setContentType("text/html;character=utf-8"); String comments = req.getParameter("comments"); System.out.println("接收到了客户请求"+comments); resp.getWriter().write(comments); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
运行结果