Загрузка файла Apache Commons - Поток неожиданно завершился - PullRequest
5 голосов
/ 16 июля 2010

Ну, я должен сказать, что до сих пор, этот один поставил меня в тупик. Наше веб-приложение, которое работает в 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: Это оказалось проблемой с брандмауэром клиентов. Похоже, что они ... э-э ... не совсем правдивы, когда сказали, что точно знали, что это не проблема брандмауэра.

1 Ответ

1 голос
/ 14 января 2011

Может быть, вам нужны tcpdump / wireshark неправильные и правильные загрузки, а затем сравнить их?

...