我在我的Java项目中使用Apache commons fileupload 1.4库。 我有一个具有经典形式的html部分,带有文件输入和一些隐藏字段。
我仅使用Firefox> = 52上载> 500ko左右的文件时遇到问题
它与Chrome或Internet Explorer中10mo的文件兼容。 但是,使用Firefox,我在提交表单后等待了几分钟才超时。
经过一些调试,我发现造成超时的代码是:
List<FileItem> items = (new ServletFileUpload(new DiskFileItemFactory())).parseRequest(request);
有原因等待的部分是“ parseRequest”。
我尝试使用IntelliJ中的调试器调试请求的内容,但是无法以原始格式复制此请求对象的整个内容值。
在以下情况下有效: -Firefox:版本<= 52或文件大小<500ko(大约不是很精确) - IE浏览器 -Chrome
没有文件大小限制,这似乎取决于请求的大小,因为解析请求部分花费了太多时间...
在两种情况下,我都收到了带有Firefox扩展名的HTTP请求。 一个生成的文件上传失败的3mo文件(请求文件很大,是上传文件大小的3倍): https://code.empreintesduweb.com/13561.html
一个生成的上传文件200ko有效(请求文件很小): https://code.empreintesduweb.com/13560.html
实际上,主要区别在于在Chrome或IE中,请求标头中没有上传文件的原始内容:
具有的部分: 对象 流 .... 尾流 endobj
仅在Firefox中显示...
答案 0 :(得分:2)
一些值得在这里尝试的事情:
MultipartConfig
,它似乎提供了maxFileSize
和maxRequestSize
这样的属性(请参阅:https://www.codejava.net/java-ee/servlet/java-file-upload-example-with-servlet-30-api#maxFileSize%28%29)如果您提供更多信息(例如apache / java / servlet的版本)以及更多代码(尤其是request
的定义),我们也可能会更好地帮助您
一些有用的资源:
XMLHttpRequest
Sending_files_using_a_FormData_object
How to set a header for a HTTP GET request, and trigger file download?
答案 1 :(得分:2)
您可以尝试设置最大文件大小,也许文件大小超过了最大阈值。根据documentation:
- 上载的项目应保留在内存中,只要它们很小即可。
- 较大的项目应写入磁盘上的临时文件中。
- 不允许很大的上传请求。
- 内置默认设置为要保留在内存中的最大项目大小,允许的最大上传大小 请求,并且可以接受临时文件的位置。
尝试以下方法:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// Set factory constraints
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(yourMaxMemorySize);
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
List<FileItem> items = new ServletFileUpload(factory).parseRequest(request);
for (FileItem item : items) {
if (item.isFormField()) {
// Process regular form field (input type="text|radio|checkbox|etc", select, etc).
String fieldName = item.getFieldName();
String fieldValue = item.getString();
// ... (do your job here)
} else {
// Process form file field (input type="file").
String fieldName = item.getFieldName();
String fileName = FilenameUtils.getName(item.getName());
InputStream fileContent = item.getInputStream();
// ... (do your job here)
}
}
} catch (FileUploadException e) {
throw new ServletException("Cannot parse multipart request.", e);
}
// ...
}
在这里,由于文件很大,我们正在为文件提供临时位置。
答案 2 :(得分:0)
尝试使用setMaxInactiveInterval方法设置会话超时
request.getSession().setMaxInactiveInterval(1200);
参数指定客户端请求之前到请求之间的时间(以秒为单位) Servlet容器将使该会话无效。间隔值 零或更少表示会话永不超时。
答案 3 :(得分:0)
感谢您的所有回答。 最后,我成功解决了这个问题,但实际上...并非如此。 我注意到表格中有一些特定的内容。 我有两个输入,一个是标准文件输入,另一个是在任何上传之前接收一些奇怪的js在base64中编码的文件内容。 所以我只有一次文件的原始内容,还有base64中的文件。为什么呢?我不知道。
但是我删除了所有这些,我创建了一个带有标准输入文件的新的简洁表格。 我使用的是ServletFileUpload中的流API,它可以正常工作,大文件只需几秒钟。
所以我不了解所有内容(例如,为什么问题只在某些浏览器上出现),但是我找到了解决方法;)
谢谢!