Вызывает ли Tomcat метод doPost сервлета до или после получения тела сообщения? - PullRequest
0 голосов
/ 22 октября 2018

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

Я создалпростой сервлет, расширяющий класс HttpServlet и реализующий метод doPost(request, response).В рамках моего метода я звоню request.getInputStream(), чтобы получить тело сообщения через поток ввода.

Предположим, что клиент публикует очень большой объект, и в процессе загрузки клиент прерывает загрузку или ихне удается подключиться к интернету.Мой doPost метод никогда не будет вызван в этом случае?Или он будет вызван, но потерпит неудачу во время чтения входного потока?

Разница важна для меня, потому что я хочу выяснить, смогу ли я поймать IOException во время вводаПоток читать и предпринимать какие-то действия там.

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Метод doPost() будет вызываться перед чтением тела.

В обычных запросах POST тело читается и потребляется при вызове request.getParameter(..), .getParameterNames(), .getPart(..) или .getParts(),Если вы можете вызвать request.getInputStream(), это означает, что тело еще не прочитано.

С протоколом HTTP / 1.1 сервер может отправить подтверждение клиенту (100 Continue), если клиент запросилдля него с заголовком Expect.Это происходит как раз перед чтением тела.

0 голосов
/ 22 октября 2018

Глядя на исходный код Tomcat, мы видим, что реализацией ServeltInputStream по умолчанию является CoyoteInputStream, которая читает из экземпляра org.apache.catalina.connector.InputBuffer.Этот буфер имеет различные классы расширения, которые зависят от протокола.Похоже, что тело запроса, полностью прочитанное до вызова doPost(), является подробностью реализации в зависимости от используемого протокола, например, для HTTP2 в классе StreamInputBuffer мы видим следующий комментарий:

Два буфератребуется, чтобы избежать различных проблем многопоточности.Эти проблемы возникают из-за того, что поток (или запрос / ответ), используемый приложением, обрабатывается в одном потоке, а соединение обрабатывается в другом.Следовательно, возможно, что кадр тела запроса может быть получен до того, как приложение будет готово его прочитать.Если оно не буферизовано, обработка соединения (и, следовательно, всех потоков) будет блокироваться, пока приложение не прочитает данные.Следовательно, входящие данные должны быть в буфере.Если был использован только один буфер, он мог быть поврежден, если поток соединения пытается добавить его в то же время, когда приложение его считывает.В то время как должна быть возможность избежать этого искажения путем осторожного использования буфера, для него все равно потребуются те же копии, что и для двух буферов, и поведение будет менее ясным.

Это относится к другим контейнерам сервлетов, напримерJBoss WildFly может начать выполнение doPost() до того, как тело запроса будет полностью прочитано на основании [WFLY-6671] ajp-соединения зависает, если заголовок почтового HTTP-запроса содержит «Transfer-Encoding: chunked» , если соединение может зависнуть внутри.

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