那么,我不得不说,迄今为止,这一个让我难住。我们在Tomcat 6.0.18中运行的Web应用程序在文件上载过程中失败,但仅当客户端机器是Windows机器时,仅适用于某些机器和所有浏览器,而不仅仅是IE时,。Apache Commons文件上传 - 流意外结束
日志中有一个堆栈跟踪,这似乎表明客户端关闭了连接,或者流以某种方式损坏了。堆栈跟踪的根本原因如下:
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上找到了一些that may be related。似乎表明Tomcat 6中存在一些bug,它在6.0.20版本中修复了一个稍微高于我们正在使用的版本的版本。不幸的是,它没有提到问题本身。我在Tomcat changelog上有had a look,但是看不到任何可能导致此问题的bug。
无论如何,关于我的实际问题,有没有人遇到类似的问题,如果是的话,那么根本问题是什么,你是如何解决它的?
非常感谢您的回复。
编辑:这似乎是负载平衡和Tomcat的某种问题。如果绕过负载均衡器并直接通过服务器IP地址访问Tomcat,问题就会消失。奇怪的是,这出现在我们使用Apache/AJP1.3的分段环境中,以及我们使用Zeus的live中。
编辑3:这原来是客户端防火墙的问题。看起来他们是..呃..当他们说明确知道这不是防火墙问题时,他们并不完全真实。
你愿意详细说明这个问题的答案究竟是什么吗? – MattC 2011-01-14 16:09:57
Matt,我很抱歉,但我不确切知道防火墙问题是什么。我们只是简单地联系客户后的防火墙修复程序,并通知它是一个防火墙问题。 – Jon 2011-01-24 12:53:18