自 Firefox 74 版本以来,使用“multipart/form-data”表单发送的文件大小超过约 1.8 MB 的文件会引发错误。
注意:使用 AJAX 发送的文件工作正常。只有多部分表单提交会导致问题。
HTML 代码:
<form name="formUpload" action="AdminImportInssAseg" method="POST"
enctype="multipart/form-data" onsubmit="return validate_form(this);">
<table class="centrado green">
<tr>
<td><input type="File" name="miadjuntoSolvenciaX" class="mdt">
</td>
</tr>
<tr>
<td align="center" colspan="2"><a href="#"
onClick="if(validate_form(formUpload)) formUpload.submit();"
title="Importar el archivo"><img alt='' border="0"
src="./images/add.gif" height="30"></a></td>
</tr>
</table>
</form>
Java代码:
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
if (item.isFormField()) {
continue;
} else {
filename = item.getName();
contentType = item.getContentType();
String inputLine;
InputStream fis = item.openStream();
BufferedReader in = null;
in = new BufferedReader(new InputStreamReader(fis,"ISO-8859-1"));
while ((inputLine = in.readLine()) != null) {
try{
out.println("*"+inputLine+"*<br>");
}
catch (Exception e){
out.println("<p>Error: <b>"+e.getMessage() + "</b></p>");
}
}
fis.close();
}
}
我可以看到它读取文件,但在使用 Firefox 74+ 时失败。
可以在此消息下方找到错误堆栈跟踪。
使用 Firefox 73 或更低版本时,一切正常。
直接连接到 Tomcat 端口(不使用 AJP 连接器)时,一切正常(包括使用 Firefox 74/75)。
代码已经使用了十多年。 Java编码、Apache和Tomcat最近没有修改过。
Server version: Apache/2.4.43 (Linux/SUSE)
我注意到保存的“临时”文件总是被剪切为 188416 字节(而上传的文件实际上更大)。
csimon@linux-069t:/tomcat/temp> l
total 376
drwxr-xr-x 2 csimon users 4096 may 1 10:53 ./
drwxr-xr-x 9 csimon users 4096 ago 29 2018 ../
-rw-r--r-- 1 csimon users 188416 may 1 10:45 EMP59_AF_GA_202005011.CSV
-rw-r--r-- 1 csimon users 188416 may 1 10:37 EMP59_AF_GA_20200501.CSV
生产用户报告了问题,但我可以在本地重现它。
只有使用 Firefox 74 和 75 才会出现此问题(我使用 Firefox 71 -> 75 进行测试),因此它一定与 Firefox 中的某些更改有关(至少 Linux 和 Windows 版本)。我在 Firefox 发行说明中找不到解释。 任何人都知道可能导致此问题的原因以及如何解决此问题。
我过去已经遇到过 Firefox 升级相关的问题,通常是通过“about:config”更改 Firefox 配置中的某些值来修复。诀窍是找到正确的参数来更新...
使用 Firefo 74+ 时来自 AJP 连接器日志的错误日志:
[Sat May 02 18:27:55.801 2020] [15619:139986498496512] [info] init_jk::mod_jk.c (3591): mod_jk/1.2.46 initialized
[Sat May 02 18:27:55.805 2020] [15619:139986498496512] [info] init_jk::mod_jk.c (3591): mod_jk/1.2.46 initialized
[Sat May 02 18:28:02.669 2020] [15641:139986189342464] [info] ajp_process_callback::jk_ajp_common.c (2074): (ajp13) Writing to client aborted or client network problems
[Sat May 02 18:28:02.669 2020] [15641:139986189342464] [info] ajp_service::jk_ajp_common.c (2775): (ajp13) sending request to tomcat failed (unrecoverable), because of client write error (attempt=1)
[Sat May 02 18:28:02.670 2020] [15641:139986189342464] [info] jk_handler::mod_jk.c (2984): Aborting connection for worker=ajp13
[Sat May 02 18:28:15.289 2020] [15641:139986189342464] [info] ajp_read_into_msg_buff::jk_ajp_common.c (1550): (ajp13) receiving data from client failed. Connection aborted or network problems
[Sat May 02 18:28:15.289 2020] [15641:139986189342464] [info] ajp_process_callback::jk_ajp_common.c (2102): (ajp13) Reading from client aborted or client network problems
[Sat May 02 18:28:15.289 2020] [15641:139986189342464] [info] ajp_service::jk_ajp_common.c (2775): (ajp13) sending request to tomcat failed (unrecoverable), because of client read error (attempt=1)
[Sat May 02 18:28:15.310 2020] [15641:139986189342464] [info] jk_handler::mod_jk.c (2984): Aborting connection for worker=ajp13
使用 Firefox 74+ 时 Tomcat 错误堆栈跟踪:
java.io.IOException: Fallo en lectura de Conector
at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:313)
at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:364)
at org.apache.coyote.ajp.AjpProcessor.receive(AjpProcessor.java:331)
at org.apache.coyote.ajp.AbstractAjpProcessor.refillReadBuffer(AbstractAjpProcessor.java:662)
at org.apache.coyote.ajp.AbstractAjpProcessor$SocketInputBuffer.doRead(AbstractAjpProcessor.java:1140)
at org.apache.coyote.Request.doRead(Request.java:422)
at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290)
at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:449)
at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315)
at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:200)
at com.oreilly.servlet.multipart.BufferedServletInputStream.fill(BufferedServletInputStream.java:64)
at com.oreilly.servlet.multipart.BufferedServletInputStream.readLine(BufferedServletInputStream.java:108)
at com.oreilly.servlet.multipart.LimitedServletInputStream.readLine(LimitedServletInputStream.java:60)
at com.oreilly.servlet.multipart.PartInputStream.fill(PartInputStream.java:97)
at com.oreilly.servlet.multipart.PartInputStream.read(PartInputStream.java:195)
at com.oreilly.servlet.multipart.PartInputStream.read(PartInputStream.java:156)
at com.oreilly.servlet.multipart.FilePart.write(FilePart.java:208)
at com.oreilly.servlet.multipart.FilePart.writeTo(FilePart.java:167)
at com.oreilly.servlet.MultipartRequest.<init>(MultipartRequest.java:271)
at servlet.presentacion.admin.AdminImportInssAseg.doPost(AdminImportInssAseg.java:101)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:193)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
最佳答案
使用 com.oreilly.servlet.MultipartRequest 失败。 使用 org.apache.commons.fileupload 失败。
使用 Java Servlet 技术使其工作并将 maxFileSize 设置得更高(默认值为 2MB)。
我不明白为什么它适用于旧版本的 Firefox 而不适用于新版本......但我的问题已经解决了。
@WebServlet("/AdminImportInssAseg")
@MultipartConfig (fileSizeThreshold=1024*1024*10, // 1 MB
maxFileSize=1024*1024*50, // 50 MB
maxRequestSize=1024*1024*100) // 100 MB
public class AdminImportInssAseg extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,
IOException {
Part filePart = request.getPart("miadjuntoSolvenciaX"); // Retrieves <input type="file" name="file">
filename = filePart.getName();
fileSize = filePart.getSize();
contentType = filePart.getContentType();
InputStream fis = filePart.getInputStream();
BufferedReader in = null;
in = new BufferedReader(new InputStreamReader(fis,"ISO-8859-1"));
String inputLine;
while ((inputLine = in.readLine()) != null) {
...
}
fis.close();
filePart.delete();
}
}
关于从 Firefox 74/75 发布 multipart/form-data 并在服务器端使用 Apache AJP 连接器时出现 java.io.IOException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61547312/