![](/img/trans.png)
[英]Why did I get “FileUploadException: Stream ended unexpectedly” with Apache Commons FileUpload?
[英]Apache Commons File Upload - Stream ended unexpectedly
好吧,我不得不说到目前为止,这个让我难过。 我们在Tomcat 6.0.18中运行的Web应用程序在文件上载期间失败,但仅当客户端计算机是Windows计算机时,仅适用于某些计算机,并且适用于所有浏览器,而不仅仅是IE 。
日志中有一个堆栈跟踪,这似乎表明客户端关闭了连接,或者流以某种方式被破坏。 堆栈跟踪的根本原因如下:
Caused by: org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:983)
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:887)
at java.io.InputStream.read(InputStream.java:85)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:94)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:64)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:362)
... 70 more
导致跟踪的代码看起来相当直接。
private Map<String, Object> getMap( ActionRequest request ) {
HashMap<String, Object> parameters = new HashMap<String, Object>();
if ( request == null ) {
return parameters;
}
if ( request.getContentType() == null ) {
return parameters;
}
try {
if(PortletFileUpload.isMultipartContent(request)){
DiskFileItemFactory factory = new DiskFileItemFactory();
PortletFileUpload upload = new PortletFileUpload(factory);
List<DiskFileItem> fileItems = upload.parseRequest(request);
for( DiskFileItem fileItem : fileItems ) {
String name = fileItem.getFieldName();
//now set appropriate variable, populate hashtable
if( fileItem.isFormField() ) {
String value = fileItem.getString( request.getCharacterEncoding() );
if( parameters.get( name ) == null ) {
String[] values = new String[1];
values[0] = value;
parameters.put( name, values );
} else {
Object prevobj = parameters.get( name );
if( prevobj instanceof String[] ) {
String[] prev = ( String[] ) prevobj;
String[] newStr = new String[prev.length + 1];
System.arraycopy(
prev, 0, newStr, 0,
prev.length
);
newStr[prev.length] = value;
parameters.put( name, newStr );
} else {
//now what? I think this breaks the standard.
throw new EatMyHatException(
"file and input field with same name?"
);
}
}
} else {
// Yes, we don't return FileParameter[] for multiple files of same name. AFAIK, that's not allowed.
FileParameter fp = new FileParameter( fileItem );
parameters.put( name, fp );
files.add( fp );
}
}
} else {
// Not multipart
return toObjectMap(request.getParameterMap());
}
} catch (FileUploadException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return parameters;
}
让我们感到悲伤的是这一行:
List<DiskFileItem> fileItems = upload.parseRequest(request);
由于某种原因,决定来自某些Windows机器的流在某种程度上被破坏了。
我想我已经找到了可能与 StackOverflow 相关的东西。 它似乎表明Tomcat 6中存在一些错误,它在版本6.0.20中得到修复,比我们使用的版本略高。 不幸的是,它没有提到问题本身是什么。 我已经看过 Tomcat更改日志了,但看不到任何可能导致此问题的bug的候选者。
无论如何,就我的实际问题而言,是否有人遇到类似问题,如果是,那么根本问题是什么?你是如何解决它的?
提前感谢您的任何回复。
编辑:这似乎是负载平衡和Tomcat的某种问题。 如果绕过负载均衡器并通过服务器IP地址直接访问Tomcat,问题就会消失。 奇怪的是,这出现在我们使用Apache / AJP1.3的暂存环境中,以及我们使用Zeus的直播环境。
编辑3:这结果是客户端防火墙的问题。 看来他们是......呃..当他们说明确知道这不是防火墙问题时,并不是完全真实的。
可能你需要tcpdump / wireshark糟糕和正确的上传,然后比较它们?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.