一、遇到的问题:
接口上传了一个文件,从HttpServletRequest 中获取了文件名、文件内容等信息,后面再从HttpServletRequest 中读取文件名信息、文件内容就读取不到了
二、原因:
因为流是单向的,就像水一样被舀了一瓢就会少一瓢。所以 HttpServletRequest 对象中的 InputStream 或者 Reader 只能使用一次。
三、解决办法:
那该怎么办,复制一份HttpServletRequest 对象,把流转为字节数组存储,使用时再从字节数组中获取,可以解决。
1.用到以下依赖将输入流转化为字节数组:
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
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();
}
};
}
}
四、测试:
测试里用到以下依赖来获取文件信息:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
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<FileItem> 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<FileItem> 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
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80238.html