#java #multithreading #servlets
#java #многопоточность #сервлеты
Вопрос:
В общем, мне нужно загрузить большой файл через html-форму, вызывающую сервлет, а затем обработать этот файл с помощью сложного алгоритма и вернуть XML-документ в качестве ответа. Весь этот процесс занимает много времени, поэтому, чтобы избежать тайм-аута подключения браузера, я решил создать объект (расширяющийся Thread
), который будет выполнять трудоемкий процесс (загрузка файла и манипулирование им) в другом потоке и который сможет указывать на ход процесса. Чтобы сделать это, мне нужно передать HttpServletRequest
запрос в качестве аргумента объекту. Когда я попытался проанализировать параметр запроса (я использую apache commons FileUpload), я получил следующее исключение:
"the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is null" .
Возможно ли передать HttpServletRequest
объект в поток, расширяющий объект? если да, какова правильная практика безопасного выполнения этого?
Комментарии:
1. содержит ли ваша html-форма атрибут enctype со значением
multipart/form-data
?2. ДА. Я могу легко сделать это в методе doPost, проблема заключается в том, когда я передаю запрос в качестве параметра.
Ответ №1:
Вы не должны. Когда объект запроса используется в потоке, запрос может быть недействительным, и Tomcat, возможно, очистил его (отсюда ваше исключение) (конечно, предполагая, что ваша форма действительно является enctype="multipart/form-data"
)
Итак, чтобы обработать это должным образом, извлеките данные из запроса и передайте их новому потоку. Таким образом, вы не будете зависеть от объекта запроса — только от его содержимого.
Обратите внимание, что Servlet 3.0 добавляет опцию для асинхронной обработки на стороне сервера, которая кажется вам хорошим вариантом — проверьте это.
Комментарии:
1. Спасибо, что указали на асинхронную обработку на стороне сервера, я рассмотрю это. Я хотел запретить браузеру ждать, пока я не закончу извлечение файла из запроса (как я делаю сейчас в методе doPost), поэтому я подумал о выполнении этого в другом потоке. Так что, невозможно передать запрос в качестве аргумента?
2. простое получение данных из него не должно быть дорогостоящим, поэтому вместо этого получите данные и передайте их потоку.
3. Можете ли вы немного подробнее объяснить о том, что «запрос, возможно, больше не действителен»? Черт возьми, этому ответу несколько лет, вероятно, никто не увидит этот комментарий.
Ответ №2:
Ошибка, которую вы получаете, указывает на то, что форма на стороне клиента, возможно, настроена неправильно. Убедитесь, что ваша форма определяется следующим образом:
<FORM action="YOUR_SERVLET"
enctype="multipart/form-data"
method="post">
Комментарии:
1. Это так. Я легко делаю это в методе doPost, проблема заключается в том, когда я передаю запрос в качестве параметра.