1、问题:HttpServletRequest 的 getInputStream() 和 getReader() 都只能读取一次,由于 Request Body 是流的形式读取,流读了一次就没有,所以只能被调用一次,调用第二次就报错了。
2、解决方案:自定义HttpServletRequest包装类BodyReaderHttpServletRequestWrapper,然后放到过滤链
具体:先将 Request Body 保存,然后通过 Servlet 自带的 HttpServletRequestWrapper 类覆盖 getReader() 和getInputStream() 方法,使流从保存的body读取。然后再Filter中将ServletRequest替换为AuthenticationRequestWrapper。
package cn.gbits.oa.kernelsdk.security.xss;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.StringUtils;
import cn.gbits.oa.kernelsdk.utils.JsoupUtil;
import cn.gbits.oa.kernelsdk.utils.SerializeUtils;
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
private String requestBody = null;
HttpServletRequest orgRequest = null;
private boolean isIncludeRichText = false;
private Map<String, String[]> requestMap = null;
public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
orgRequest = request;
if (requestBody == null) {
try {
requestMap = new HashMap<String, String[]>();
requestBody = JsoupUtil.clean(readBody(request)).replaceAll(" ", "").replaceAll("&