Фраза причины ответа Джерси противоречива в 7 и 8,5.

Я использую Tomcat 8.5 на одном сервере и Tomcat 7 на другом сервере, и у меня есть следующий ресурс Джерси:

@Path("main")
public class MyResource {


@POST
@Path("path")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public PojoResponse sendMailTemplate(PojoRequest paramsMap) throws Exception {
    return service.execute(paramsMap);
}

Который зарегистрирован в MyApplication (extends ResourceConfig) с @ApplicationPath("root")

При отправке запроса с использованием JMeter/Postman (в /root/main/path) я получаю противоречивую фразу причины HTTP

Клиент не обязан проверять или отображать фразу-причину.

Что не обязательно для протокола

Приведенные здесь фразы-причины являются лишь рекомендациями - они МОГУТ заменяться местными эквивалентами, не влияя на протокол.

Я вижу "правильный" ответ 200 OK от сервера Tomcat 7:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: application/json
Content-Length: 32

и "неверный" ответ 200 200 от сервера Tomcat 7 (тот же запрос):

HTTP/1.1 200 200
Server: Apache
Content-Type: application/json
Content-Length: 32
X-Content-Type-Options: nosniff
X-XSS-Protection: 1
Connection: close
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

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

РЕДАКТИРОВАТЬ

Моё приложение также регистрирует JacksonFeature:

register(JacksonFeature.class);

РЕДАКТИРОВАТЬ 2

На самом деле я обнаружил, что у меня есть дополнительная банка во второй среде:

 jersey-entity-filtering-2.19

Общие банки:

jersey-client-2.19.jar
jersey-common-2.19.jar
jersey-container-servlet-2.19.jar
jersey-container-servlet-core-2.19.jar
jersey-guava-2.19.jar
jersey-media-jaxb-2.19.jar
jersey-media-json-jackson-2.6.jar
jersey-server-2.19.jar
jersey-spring3-2.6.jar

РЕДАКТИРОВАТЬ 3

Я обнаружил ошибку в Tomcat 8.5, из-за которой фраза причины была удалена

Кристофер Шульц: Я был удивлен, увидев, что Tomcat активно удаляет причину. Сначала я думал, что это просто Tomcat, удаляющий фразы-причины из каждого ответа, генерируемого Tomcat (например, все, что происходит из DefaultServlet, различные внутренние ошибки и т. Д.), Но он активно удаляет фразы-причины, явно установленные приложениями.

Михаил Осипов: Нет, это не дает повода фразы. Только страница с ошибкой HTML. Я знаю, потому что я переписал ErrorReportValve в последний раз.

РЕДАКТИРОВАТЬ 4

Я нашел соответствующий вопрос, но не до конца его понял

Tomcat 8.5 удалил "фразу причины состояния HTTP" из ответа, поэтому вы получите HTTP 200 вместо HTTP 200 OK в ответе. Возможно, ваши наблюдения взяты из программного обеспечения, которое дублирует код состояния в фразу причины состояния для отображения.

Как вы соблюдаете код статуса? Вы можете обнаружить, что если вы выполните трассировку протокола, вы увидите, что Tomcat / httpd отправляет только один код состояния. Вы уверены, что "двойной код состояния" на самом деле не является (нормальным) кодом состояния и фразой причины, которая оказывается тем же текстом, что и код состояния?

3 ответа

Решение

Я только что ответил на аналогичный вопрос (52821653) два дня назад.

Вкратце: текущая версия протокола HTTP (HTTP/2) убрала поддержку фразы причины.

Эта функция исчезла. Не надейся на это.

ОБНОВЛЕНИЕ:

Смотря на

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1

а также

HTTP/1.1 200 200
Server: Apache

HTTP-соединитель текущих версий Tomcat 8.5 по умолчанию будет отвечать HTTP/1.1 200 (без фразы причины). Увидеть org.apache.coyote.http11.Http11OutputBuffer,

Коннектор AJP текущих версий Tomcat 8.5 по умолчанию будет отвечать HTTP/1.1 200 200 (используя код состояния в качестве фразы причины) из-за ограничений некоторых HTTP-серверов. Увидеть org.apache.coyote.ajp.AjpProcessor,

Оба ответа являются действительными.

Создание строки "ОК" можно включить в Tomcat 8.5, установив sendReasonPhrase="true" на соединителе. Эта опция устарела.

Я думаю, что ответ, который вы ищете, может быть найден в RFC 2616, раздел 6.

Соответствующая выдержка:

Код состояния предназначен для использования автоматами, а фраза разума предназначена для пользователя. Клиент не обязан проверять или отображать фразу-причину.

Основной вывод заключается в том, что в вашем клиентском коде нельзя полагаться на фразу-причину. Однако вы можете и должны полагаться на код статуса.

Если вы хотите передать дополнительный понятный человеку контекст в ваших HTTP-ответах, то обычно это помещают в "настраиваемый" заголовок ответа (например, "X-MyApp-Message"). Обратите внимание, что пользовательские заголовки должны начинаться с "X-".

Проблема заключалась в использовании Apache Server 2.4.6 с ошибкой. Одним из изменений Apache 2.4.7 является исправление возвращаемой фразы причины:

core: добавить отсутствующие Reason-Phrase в заголовки HTTP-ответа. PR 54946. [Райнер Юнг]

Соответствующая ошибка гласит, что это серьезное изменение:

мы получили бы строку состояния http, извлеченную из стандартной таблицы, например:

HTTP/1.1<sp>200<sp>OK

Теперь в Apache 2.2.24 мы получаем:

HTTP/1.1<sp>200<sp>

Мы отследили это до изменений, сделанных для ошибки Apache 44995, которые вызвали это новое поведение. Эта ошибка была исправлена ​​для обработки пользовательских кодов состояния, но она также приводила к нарушению стандартных кодов, так что она больше не возвращала стандартные расширенные ответы на слова-фразы.

Я понимаю, что спецификация RFC2616 допускает ответ HTTP/1.1200, но наш клиент не изменяется и вылетает при отсутствии фразы-причины.

Другие вопросы по тегам