Jersey 响应的原因短语在 tomcat 7 和 8.5 中不一致

Jersey response's reason phrase is inconsistent in tomcat 7 and 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);
}

@ApplicationPath("root")

注册到 MyApplication (extends ResourceConfig)

当使用 JMeter/Postman 提交请求时(到 /root/main/path)我得到不一致的 HTTP Reason Phrase

The client is not required to examine or display the Reason- Phrase.

这对协议来说不是强制性的

The reason phrases listed here are only recommendations -- they MAY be replaced by local equivalents without affecting the protocol.

我看到来自 Tomcat 7 服务器的 200 OK 的“有效”响应:

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

以及来自 Tomcat 7 服务器(相同请求)的 200 200 的“无效”响应:

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

当我检查 Response 时,我没有找到任何关于更新原因短语的参考, 那么这种不一致是应该忽略还是可以修复?

编辑

我的应用程序还注册了 JacksonFeature:

register(JacksonFeature.class);

编辑 2

实际上我发现我在第二个环境中有额外的jar:

 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 中发现了一个 bug,其中说原因短语 已被删除

Christopher Schultz : I was surprised to see that Tomcat actively strips-out the reason phrase. I had initially thought this was simply Tomcat removing reason-phrases from every response generated by Tomcat (e.g. everything coming from the DefaultServlet, various internal errors, etc.), but it's actively stripping reason phrases explicitly-set by applications.

Michael Osipov: No, this does not send any reason phrase. Only the HTML error page. I know, because I have rewritten the ErrorReportValve the last time.

编辑 4

找到了但是没完全看懂

Tomcat 8.5 removed the "HTTP status reason phrase" from the response, so you'll get HTTP 200 instead of HTTP 200 OK in the response. It's possible that your observations are from software that duplicates the status code into the status reason phrase for display.

How are you observing the status code? You may find that if you do a protocol trace, you'll see that there is only a single status code being sent by Tomcat / httpd. Are you sure the "double status code" isn't actually a (normal) status code and a reason phrase that happens to be the same text as the status code?

我认为您正在寻找的答案可能在RFC 2616, section 6中找到。

相关摘录:

The Status-Code is intended for use by automata and the Reason-Phrase is intended for the human user. The client is not required to examine or display the Reason- Phrase.

主要 take-away 是您的客户端代码中不应依赖 reason-phrase。但是,您可以而且应该依赖 Status-Code.

如果您希望在 HTTP 响应中传达额外的人类可读上下文,通常的做法是将其放在 'custom' 响应 header 中(例如 "X-MyApp-Message")。请注意,自定义 header 应以 'X-' 开头。

两天前我刚回答(52821653)

简而言之:当前版本的 HTTP 协议 (HTTP/2) 已经删除了对原因短语的支持。

此功能已消失。不要依赖它。

更新:

正在看

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

HTTP/1.1 200 200
Server: Apache

当前版本 Tomcat 8.5 的 HTTP 连接器默认将响应 HTTP/1.1 200(无原因短语)。参见 org.apache.coyote.http11.Http11OutputBuffer

由于某些 HTTP 服务器的限制,Tomcat 8.5 当前版本的 AJP 连接器默认将响应 HTTP/1.1 200 200(使用状态代码作为原因短语)。参见 org.apache.coyote.ajp.AjpProcessor

两个回答都是有效的。

通过在 Connector 上设置 sendReasonPhrase="true",可以在 Tomcat 8.5 中启用生成 "OK" 字符串。此选项已弃用。

问题是使用 Apache Server 2.4.6,它有一个错误,Apache 2.4.7 的更改之一正在修复 reason phrase to be returned

core: Add missing Reason-Phrase in HTTP response headers. PR 54946. [Rainer Jung]

relevant bug 声明这是一个重大变更:

we would get a http status-line pulled from a standard table like:

HTTP/1.1<sp>200<sp>OK

Now, in Apache 2.2.24 we are getting:

HTTP/1.1<sp>200<sp>

We tracked this down into a change made for apache bug 44995 that caused this new behavior. The bug was a fix to handle custom status codes, but it also ended up breaking standard codes such that it no longer returned standard reason-phrase enhanced responses.

I realize that the RFC2616 specification allows for the HTTP/1.1200 response, but our client is not changeable and crashes on receiving no reason-phrase.