Ну, я должен сказать, что до сих пор, этот один поставил меня в тупик. Наше веб-приложение, которое работает в Tomcat 6.0.18, не работает во время загрузки файла, но только тогда, когда клиентская машина является машиной 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, но не вижу вероятных кандидатов на ошибку, которая может вызвать эту проблему.
В любом случае, на мой вопрос, кто-нибудь сталкивался с подобной проблемой, и если да, то какова была основная проблема и как вы ее решили?
Заранее благодарю за любые ответы.
РЕДАКТИРОВАТЬ: Это, кажется, какая-то проблема с балансировкой нагрузки и Tomcat. Если вы обойдете балансировщик нагрузки и получите доступ к Tomcat напрямую через IP-адрес сервера, проблема исчезнет. Странно то, что это появляется как в нашей промежуточной среде, в которой мы используем Apache / AJP1.3, так и в живую, где мы используем Zeus.
EDIT3: Это оказалось проблемой с брандмауэром клиентов. Похоже, что они ... э-э ... не совсем правдивы, когда сказали, что точно знали, что это не проблема брандмауэра.