问题:使用RequestWrapper类后,造成了部分post请求,controller无法获取到入参而导致项目部分功能不可用
原因:InputStream只可读取一次。 由于RequestWrapper里读取了InputStream,导致request的流已空,所以controller里面getParameter无法获取到内容
解决方案:根据ContentType类型做不同处理
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.StreamUtils;
public class RequestWrapper extends HttpServletRequestWrapper {
private final byte[] body;
public RequestWrapper(HttpServletRequest request) throws IOException {
super(request);
String sessionStream = getBodyString(request);
body = sessionStream.getBytes(Charset.forName("UTF-8"));
}
/**
* 获取请求Body
*
* @param request
* @return
*/
public String getBodyString(final ServletRequest request) {
String contentType = request.getContentType();
String bodyString ="";
if (StringUtils.isNotBlank(contentType) &&
(contentType.contains("multipart/form-data") ||
contentType.contains("x-www-form-urlencoded"))){
Enumeration<String> pars=request.getParameterNames();
while(pars.hasMoreElements()){
String n=pars.nextElement();
bodyString+=n+"="+request.getParameter(n)+"&";
}
bodyString=bodyString.endsWith("&")?bodyString.substring(0, bodyString.length()-1):bodyString;
return bodyString;
}
try {
byte[] byteArray = StreamUtils.copyToByteArray(request.getInputStream());
bodyString = new String(byteArray, "UTF-8");
} catch (IOException e) {
}
return bodyString;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
}
extends HttpServletRequestWrapper(已经用装饰者模式帮我们重写所有的方法,我们只需要重写自己需要重写的方法就可以了,而免去了对其它方法的进行重写的麻烦)