背景
众所周知request的输入流只能读取一次,不能重复读取,如果在过滤器或者拦截器中有业务需求对输入流进行一些其他操作,那么此处读取过后再到controller层就会报错,提示IO异常,这里采用实现HttpServletRequestWrapper
自定义一个包装器的方式解决输入流不能重复读取的问题,并实现修改流的功能,下面直接上代码!
自定义Wrapper
/**
* <p>
* 构建HttpServletRequest包装器
* </p>
*
* @author zhengshangjin
* @version 1.0.0
* @since 1.0.0
* created on 2020-04-03
*/
@Slf4j
public class CoverHttpServletRequest extends HttpServletRequestWrapper {
/**
* 存储body数据的容器(这里存储为解析流后的JSON)
*/
private String body;
/**
* 获取Body
*/
public String getBody() {
return this.body;
}
/**
* 重写Body
*/
public void setBody(String body) {
this.body = body;
}
/**
* copy stream
*
* @param request 当前的 HTTP 请求
* @throws IllegalArgumentException if the request is null
* @author zhengshangjin
* created on 2020-04-03
*/
public CoverHttpServletRequest(HttpServletRequest request) {
super(request);
body = RequestUtil.getRequestBody(request);
}
/**
* override stream
*
* @param request 当前的 HTTP 请求
* @param context 重写内容
* @throws IllegalArgumentException if the request is null
* @author zhengshangjin
* created on 2020-04-03
*/
public CoverHttpServletRequest(HttpServletRequest request, String context) {
super(request);
body = context;
}
/**
* 默认行为在包装的请求对象上返回 getReader()
*
* @return BufferedReader
* @author zhengshangjin
* created on 2020-04-03
*/
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
/**
* 默认行为在包装的请求对象上返回 getInputStream()
*
* @return BufferedReader
* @author zhengshangjin
* created on 2020-04-03
*/
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
}
解析流工具
/**
* 获取Request中Body
*
* @param request 当前的 HTTP 请求
* @return String
* @author zhengshangjin
* created on 2020-04-03
*/
public static String getRequestBody(HttpServletRequest request) {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stringBuilder.toString();
}
Q.E.D.