- 一、遇到的问题:
- 二、原因:
- 三、解决办法:
- 四、测试:
接口上传了一个文件,从HttpServletRequest 中获取了文件名、文件内容等信息,后面再从HttpServletRequest 中读取文件名信息、文件内容就读取不到了
二、原因:因为流是单向的,就像水一样被舀了一瓢就会少一瓢。所以 HttpServletRequest 对象中的 InputStream 或者 Reader 只能使用一次。
三、解决办法:那该怎么办,复制一份HttpServletRequest 对象,把流转为字节数组存储,使用时再从字节数组中获取,可以解决。
1.用到以下依赖将输入流转化为字节数组:
commons-io commons-io 2.11.0
2.MyHttpServletRequest类继承HttpServletRequestWrapper:
import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
public class MyHttpServletRequest extends HttpServletRequestWrapper {
private byte[] body;
public MyHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
try {
body = IOUtils.toByteArray(request.getInputStream());
} catch (IOException ex) {
body = new byte[0];
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
ByteArrayInputStream bais = new ByteArrayInputStream(body);
@Override
public int read() throws IOException {
return bais.read();
}
};
}
}
四、测试:
测试里用到以下依赖来获取文件信息:
commons-fileupload commons-fileupload 1.3.2
public void addNewAttachment(HttpServletRequest request, HttpServletResponse response) throws Exception {
//将request转化为newRequest,便可以使用newRequest多次读取流了
HttpServletRequest newRequest = new MyHttpServletRequestWrapper(request);
//第一次读取
FileItemFactory firlfact1 = new DiskFileItemFactory();
ServletFileUpload sfu1 = new ServletFileUpload(firlfact1);
List list1 = sfu1.parseRequest(newRequest);
for (FileItem fileItem : list1) {
DiskFileItem diskFileItem = (DiskFileItem) fileItem;
String fileName = diskFileItem.getName();
System.out.println(fileName);
}
//第二次读取
FileItemFactory firlfact2 = new DiskFileItemFactory();
ServletFileUpload sfu2 = new ServletFileUpload(firlfact2);
List list2 = sfu1.parseRequest(newRequest);
for (FileItem fileItem : list2) {
DiskFileItem diskFileItem = (DiskFileItem) fileItem;
String fileName = diskFileItem.getName();
tem.out.println(fileName);
}
}
参考:
How to read request.getInputStream() multiple times
HttpServletRequestWrapper example – read httpservletrequest twice



