【问题标题】:Spring Boot 1.4.0 : REST Controllers don't set reason to HTTP responseSpring Boot 1.4.0:REST 控制器不会为 HTTP 响应设置原因
【发布时间】:2017-01-17 17:37:51
【问题描述】:

我有 2 个使用 Spring Tool Suite “Spring Starter Project”创建的项目:

第一个项目: Spring Boot 1.3.7 (Release) + Web

第二个项目: Spring Boot 1.4.0 (Release) + Web

我将每个项目的@SpringBootApplication 类替换为这段代码:

@SpringBootApplication
@RestController
public class TestWebApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestWebApplication.class, args);
    }

    @RequestMapping("/hello")
    public String sayHello() {
        return "hello!";
    }
}

当我在每台服务器上调用 GET /hello 时,我会收到以下响应:

第一个项目 (1.3.7): 状态 200 (无理由)

第二个项目 (1.4.0): 状态 200 OK

这是一个错误还是我错过了什么?

此外,我无法为 1.4.0 项目设置理由。

【问题讨论】:

    标签: java spring spring-mvc spring-boot


    【解决方案1】:

    行为的变化是由于 Spring Boot 1.4 使用 Tomcat 8.5 和 Spring Boot 1.3 使用 Tomcat 8.0。 Tomcat 8.5 不发送原因短语。

    严格来说,原因短语不是必需的。在RFC 7230 中,原因短语定义为:

    reason-phrase  = *( HTAB / SP / VCHAR / ons-text )
    

    * 表示零个或多个。换句话说,原因短语为空是合法的。

    Tomcat 8.5 利用这一点并通过删除原因短语来节省一些带宽。如果这给您的客户带来了问题,那么它可能不符合规范,因为上面链接的 RFC 部分有这样的说法:

    reason-phrase 元素的存在唯一目的是提供与数字状态代码相关的文本描述,主要是出于对早期 Internet 应用程序协议的尊重 更常用于交互式文本客户端。客户应该 忽略原因短语内容。

    您还没有说缺少原因短语是否会导致问题。如果不是,那么你最好的做法就是不要担心它并继续前进。如果您出于某种原因确实想保留原因短语,那么切换到 Undertow 或 Jetty 是您最好的选择。

    【讨论】:

    • 感谢您的回复。其实是Spring cloud的一个问题:远程服务器无故响应,Feign不起作用。有这样的代码: if (code == null || reason == null) { throw....
    • 已在 5 个月前在 open Feign 中修复:github.com/OpenFeign/feign/commit/… 。显然尚未发布
    【解决方案2】:

    我用 feign 提出了一个错误,它几乎立即被修复了.. 请查看https://github.com/OpenFeign/feign/issues/382

    谢谢, KK

    【讨论】:

    • 我没有看到 tout réponse,但谢谢。我确实找到了提交。
    【解决方案3】:

    最初,原因短语已被 Tomcat-8.5 删除。
    但是,后来提供了一个补丁来使用 Http 连接器 中的属性对其进行配置。

    您所要做的就是设置sendReasonPhrase="true" 属性,它会像以前一样工作。


    使用以下任一方法进行配置:

    方法一:更新.../apache-tomcat-8.5.x/conf/server.xml以包含如下属性:

    <Connector port="8081" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" sendReasonPhrase="true" />
    

    方法二:通过bean配置。 (在配置文件中添加)

    @Bean
    public EmbeddedServletContainerFactory servletContainerFactory() {
        TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
        factory.addConnectorCustomizers(connector ->
                ((AbstractProtocol) connector.getProtocolHandler()).setSendReasonPhrase(true));
        return factory;
    }
    

    注意:此配置将在 Tomcat-9.0.x 中删除(即:不会发送响应消息)

    参考:

    【讨论】:

      猜你喜欢
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-05
      • 2017-01-07
      • 2018-09-12
      • 2016-09-18
      • 2020-01-24
      相关资源
      最近更新 更多