过滤器与请求封装器实现字符替换

背景

  假设有个留言版程序已经上线并正常运作中,但是现在发现,有些用户会在留言中输入一些HTML标签。基于安全性的考量,不希望用户输入的HTML标签直接出现在留言中而被浏览器当作HTML的一部分。例如,并不希望用户在留言中输入com.sina.com.cn这样的信息,你不想信息在留言显示中直接变成超链接,让用户有机会在留言版中打广告,希望将一些HTML过滤掉,如将<、>角括号置换为HTML实体字符&lt;与&gt;。
  使用<、>角括号与&lt;与&gt;的区别:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <a href="www.baidu.com">点击我</a><br>
    &lt;a href=&quot;www.baidu.com&quot;&gt;点击我&lt;/a&gt;
</body>
</html>
Html Code

  上面的html文件直接使用浏览器打开后如下所示:

点击我
<a href="www.baidu.com">点击我</a>


实现分析

   1、使用过滤器来过滤请求参数。

   2、但虽然可以使用HttpServletRequest的getParameter()取得请求参数值,但就是没有一个像setParameter()的方法,可以将处理过后的请求参数重新设置给HttpServletRequest。你也许会想要亲自实现HttpServletRequest接口,让getParameter()返回过滤后的请求参数值,但这么做的话,HttpServletRequest接口定义的方法都要实现,实现所有方法非常麻烦。所幸,有个HttpServletRequestWrapper帮忙实现了HttpServletRequest接口,只要继承HttpServletRequestWrapper类,并编写想要重新定义的方法即可。相对应于ServletRequest接口,也有个ServletRequestWrapper类可以使用。


代码实现

  1、添加jar包,这里直接使用Apache Commons Lang包中的方法来实现替换字符。

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>3.4</version>
</dependency>
pom.xml

  2、请求封装器

package com.test;

import org.apache.commons.lang3.StringEscapeUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MyRequestWrapper extends HttpServletRequestWrapper {
    // 构造方法不可少,且在方法内部必须调用父类的构造方法
    public MyRequestWrapper(HttpServletRequest request) {
        super(request);
    }
    @Override
    public String getParameter(String name) {
        String parameter = getRequest().getParameter(name);
        // 使用Apache Commons Lang程序库中StringEscapeUtils类提供的escapeHtml()方法来进行字符替换
        return StringEscapeUtils.escapeHtml3(parameter);
    }
}
java Code 

  代码中定义了一个接受HttpServletRequest的构造器,真正的HttpServletRequest将通过此构造器传入,必须使用super(request)调用父类(装饰类)的构造方法,父类(装饰类)会将它赋值给一个成员变量。之后如果要取得被封装的HttpServletRequest,则可以调用getRequest()方法。

String parameter = getRequest().getParameter(name); // 被装饰对象,即原始的请求对象的方法被调用。
return StringEscapeUtils.escapeHtml3(parameter);       // 添加新功能

  3、拦截器

package com.test;

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

@WebFilter("/*")
public class RequestStringFilter implements Filter {
    private FilterConfig filterConfig;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        MyRequestWrapper myRequestWrapper = new MyRequestWrapper(request);
        chain.doFilter(myRequestWrapper, response);
    }
    public void destroy() { }
}
java Code

  4、页面

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="hello" method="post">
        <textarea rows="5" cols="100" name="message"></textarea><br>
        <input type="submit" value="提交">
    </form>
</body>
</html>
Html Code

  5、servlet

package com.test;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(urlPatterns = "/hello")
public class MyServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("UTF-8");
        String message = request.getParameter("message");

        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        PrintWriter writer = response.getWriter();

        writer.println("<!DOCTYPE html>");
        writer.println("<html>");
        writer.println("<head>");
        writer.println("<meta charset="UTF-8">");
        writer.println("<title>Title</title>");
        writer.println("</head>");
        writer.println("<body>");
        writer.print(message);
        writer.println("</body>");
        writer.println("</html>");
        writer.close();
    }
}
java Code

测试方法

  1、访问页面 http://127.0.0.1/index.html

  2、在页面中的大文本框输入:<a href="www.baidu.com">点击我</a>

  3、点击提交 

 

原文地址:https://www.cnblogs.com/Mike_Chang/p/10064800.html