Ну, я должен сказать, что до сих пор этот меня смутил. Наше веб-приложение, работающее в Tomcat 6.0.18, терпит неудачу во время загрузки файла, но только тогда, когда клиентская машина является машиной 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, в каком-то образом испорчены.
Я думаю, что нашел что-то that may be related на StackOverflow. Кажется, что в Tomcat 6 есть ошибка, которая была исправлена в версии 6.0.20, чуть более высокой версии, чем та, которую мы используем. К сожалению, он не упоминает, что такое проблема. У меня есть had a look в журнале изменений Tomcat, но я не вижу потенциальных кандидатов на ошибку, которая может вызвать эту проблему.
В любом случае, по моему фактическому вопросу, кто-нибудь сталкивался с подобной проблемой, и если да, то в чем была основная проблема и как вы ее разрешили?
Заранее благодарю за любые ответы.
РЕДАКТИРОВАТЬ: Это, по-видимому, какая-то проблема с балансировкой нагрузки и Tomcat. Если вы обойдете балансировщик нагрузки и сразу подключитесь к Tomcat через IP-адрес сервера, проблема исчезнет. Странно, что это проявляется в нашей промежуточной среде, в которой мы используем Apache/AJP1.3 и live, где мы используем Zeus.
EDIT3: Это оказалось проблемой с брандмауэром клиентов. Похоже, что они были ... не совсем правдивыми, когда говорили, что они точно знают, что это не проблема с брандмауэром.
Вы хотели бы подробно рассказать о том, что проблема была именно в ответе на этот вопрос? – MattC
Мэтт, извините, но я точно не знаю, что такое проблема с брандмауэром. Мы просто связались с клиентом post-Firewall-fix и сообщили, что это проблема с брандмауэром. – Jon