Фраза причины ответа Джерси противоречива в 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, но наш клиент не изменяется и вылетает при отсутствии фразы-причины.