2

我在一台服务器中使用 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原因短语

客户不需要检查或显示原因短语。

这对于协议不是强制性的

此处列出的原因短语只是建议——它们可以被本地等效替换而不影响协议。

我从 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

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

编辑

我的应用程序还注册了 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 中发现了一个错误,它说原因短语已被删除

Christopher Schultz:我很惊讶地看到 Tomcat 主动剥离了原因短语。我最初认为这只是 Tomcat 从 Tomcat 生成的每个响应中删除原因短语(例如,来自 DefaultServlet 的所有内容、各种内部错误等),但它正在主动剥离应用程序明确设置的原因短语。

Michael Osipov:不,这不发送任何理由短语。只有 HTML 错误页面。我知道,因为我上次重写了 ErrorReportValve。

编辑 4

我找到了相关的问题,但我没有完全理解

Tomcat 8.5 从响应中删除了“HTTP 状态原因短语”,因此您将在响应中得到 HTTP 200 而不是 HTTP 200 OK。您的观察结果可能来自将状态代码复制到状态原因短语以供显示的软件。

您如何观察状态码?您可能会发现,如果您进行协议跟踪,您会看到 Tomcat/httpd 只发送了一个状态码。您确定“双重状态代码”实际上不是(正常)状态代码和恰好与状态代码相同的文本的原因短语吗?

4

3 回答 3

5

两天前我刚刚回答了一个类似的问题(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

这两个响应都是有效的。

可以在 Tomcat 8.5 中通过设置ConnectorsendReasonPhrase="true"来启用生成“OK”字符串。此选项已弃用。

于 2018-10-18T21:00:32.693 回答
1

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

相关摘录:

状态代码供自动机使用,原因短语供人类用户使用。客户不需要检查或显示原因短语。

主要的收获是在您的客户端代码中不应依赖原因短语。但是,您可以而且应该依赖状态码。

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

于 2018-10-18T06:16:25.727 回答
0

问题是使用有错误的 Apache Server 2.4.6,Apache 2.4.7 的更改之一是修复要返回的原因短语

核心:在 HTTP 响应标头中添加缺少的原因短语。PR 54946. [Rainer Jung]

相关的错误表明这是一个重大变化:

我们会从一个标准表中得到一个 http 状态行,比如:

HTTP/1.1<sp>200<sp>OK

现在,在 Apache 2.2.24 中,我们得到:

HTTP/1.1<sp>200<sp>

我们将此追踪到对导致此新行为的 apache 错误 44995 所做的更改。该错误是对处理自定义状态代码的修复,但它最终也破坏了标准代码,因此它不再返回标准的原因短语增强响应。

我意识到 RFC2616 规范允许 HTTP/1.1200 响应,但我们的客户端是不可更改的,并且在接收不到原因短语时崩溃。

于 2018-10-24T05:28:43.413 回答