tomcat - запустить поток в сервлете и отправить ответ - PullRequest
1 голос
/ 21 марта 2011

Как я могу запустить поток, который будет работать в фоновом режиме, но ответ будет немедленно отправлен пользователю?

Я пытаюсь загрузить файл с устройства Android.Хотя процесс загрузки работает нормально, я хотел бы сообщить пользователю, что процесс завершился, как только файл был загружен с его конца.

Я проверил, что вызов ServletFileUpload.parseRequest () является тем, чтозанимает много времени.

        ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);

        List items = uploadHandler.parseRequest(request);

Так что в основном я ищу способ, которым я могу сказать пользователю «эй, вы сделали свою часть», теперь очередь сервлета выполнять всю обработку.

но я не могу, потому что parseRequest блокирует.

Я ошибаюсь, что он блокирует, потому что именно тогда он на самом деле отправляется устройством?

Загрузка наandroid:

        while (bytesRead > 0)
        {
            task.myPublishProgress(totalBytesRead, fileSize);

            dos.write(buffer, 0, bufferSize);

            bytesAvailable = fileInputStream.available();

            bufferSize = Math.min(bytesAvailable, maxBufferSize);

            bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            totalBytesRead+= bytesRead;

        }

        // send multipart form data necesssary after file data...
        dos.writeBytes(lineEnd);

        dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

        // close streams

        fileInputStream.close();

        dos.flush();

        Log.i(TAG ,"Database file with name " + this.fileName + " has been successfully written");

        InputStream is = conn.getInputStream();

        // retrieve the response from server

        int ch;

        StringBuilder b = new StringBuilder();

        while( ( ch = is.read() ) != -1 ){
            b.append( (char)ch );
        }

        dos.close();

обработка на сервере:

                DiskFileItemFactory  fileItemFactory = new DiskFileItemFactory ();

            ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
            /*
             * Parse the request
             */
            System.out.println("parsing the request....");
            **List items = uploadHandler.parseRequest(request);**
            FileItem item = (FileItem) items.get(0);
            fileName = item.getName();

            File file = new File(destinationDir, fileName);
            item.write(file);

Мне бы хотелось, чтобы сервлет не слишком блокировался в parseRequest, но вместо этого обрабатывал бы это ввозможно, что-нить, и отправить ответ клиенту.

спасибо

1 Ответ

2 голосов
/ 21 марта 2011

Это невозможно в стандартном HTTP. Ответ может быть отправлен только после полного использования тела запроса. Пока вы не позвоните uploadHandler.parseRequest(request);, файлы не будут загружены. Вы бы солгали, если бы сказали, что все готово! до этого пункта.

Только после вызова uploadHandler.parseRequest(request) и наличия предметов, вы можете честно сказать пользователю, что он сделал. Остаток, однако, может быть идеально сделан в отдельном потоке. Я бы предложил создать фиксированный пул потоков для того, что управляется ServletContextListener. Тем не менее, я думаю, что это немного преувеличено, когда вы не выполняете дорогостоящих задач с загруженными файлами.

Что касается конкретной проблемы (когда приложение, похоже, ничего не делает, когда загружает файлы), я бы предпочел решить эту проблему на стороне клиента. Получите размер файлов, запомните количество байтов, отправленных в выходной поток, а затем покажите индикатор выполнения на стороне клиента, чтобы клиент получил информацию о ходе выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...