Spring Boot 3中的@RestController使用@GetMapping为什么需要设置头部”content-length: 0″?

huangapple go评论69阅读模式
英文:

Why does my Spring Boot 3 RestController with @GetMapping require header "content-length: 0" to be set?

问题

My Spring Boot 3 @RestController@GetMapping 会响应 HTTP 状态码 400 "bad request",除非 HTTP 请求包含头部 "content-length: 0"。我使用的是 spring-boot-starter-parent:3.0.2 和所需的库。

我使用 Spring RestTemplate 编写了一个集成测试来调用我的服务。RestTemplate 请求总是包含 "content-length: 0"。这种行为对我来说是新出现的,当我设置了一个 JMeter 测试并收到 "bad request" 响应时。这是因为 JMeter 不在 GET 请求中包含 content-length。HTTP 1.1 鼓励这种行为,因为这个信息是多余的。RFC 9110

当请求消息不包含内容且方法语义不预期这样的数据时,用户代理不应发送 Content-Length 头字段。

对我来说,这似乎是 Spring Boot 3 的错误。但也许我配置错了什么?你能想到什么会触发这个问题吗?

@RestController
@RequestMapping("/v1/myService")
@Component
@Slf4j
class GetServlet {
  @GetMapping(value = "/greeting", produces = "text/plain")
  public ResponseEntity getGreeting() {
    log.debug("Sending greeting");
    return ResponseEntity.ok("Hello world!");
  }
}

删除 "produces" 参数并没有改变服务。

@RestController
@RequestMapping("/v1/myService")
@Component
@Slf4j
class GetServlet {
  @GetMapping(value = "/greeting")
  public ResponseEntity getGreeting() {
    log.debug("Sending greeting");
    return ResponseEntity.ok()
            .contentType(MediaType.valueOf("text/plain"))
            .body("Hello world!");
  }
}
英文:

My Spring Boot 3 @RestController and @GetMapping responds with HTTP status code 400 "bad request", unless the HTTP request contains header "content-length: 0". I am using spring-boot-starter-parent:3.0.2 and required libraries.

I wrote an integration test using Spring RestTemplate to call my service. The RestTemplate requests always contain "content-length: 0". This behaviour just occured to me, when I set up a JMeter test and received "bad request" responses. This is because JMeter does not include content-length in GET requests. HTTP 1.1 encourages this behaviour as the info is redundant. RFC 9110

> A user agent SHOULD NOT send a Content-Length header field when the request message does not contain content and the method semantics do not anticipate such data.

To me it seems like an error with Spring Boot 3. But maybe I have misconfigured something? Can you think of something that triggers this problem?

@RestController
@RequestMapping("/v1/myService")
@Component
@Slf4j
class GetServlet {
  @GetMapping(value = "/greeting", produces = "text/plain")
  public ResponseEntity getGreeting() {
    log.debug("Sending greeting");
    return ResponseEntity.ok("Hello world!");
  }
}

Removing parameter "produces" did not change the service.

@RestController
@RequestMapping("/v1/myService")
@Component
@Slf4j
class GetServlet {
  @GetMapping(value = "/greeting")
  public ResponseEntity getGreeting() {
    log.debug("Sending greeting");
    return ResponseEntity.ok()
            .contentType(MediaType.valueOf("text/plain"))
            .body("Hello world!");
  }
}

答案1

得分: -1

我发现,我们的项目中有一个过滤器实现,用于检查内容长度,如果缺少内容长度,则抛出“坏请求”。所以基本上Spring Boot只是按我们告诉它的方式工作。该过滤器旨在改进一个 @PostMapping,但当然,它在全局启用了。

英文:

I found out, we had a Filter implementation in our project that checked on content-length and threw "bad request" on it missing. So basically Spring Boot just did what we told it to. The filter was intented to improve a @PostMapping, but of course, it was enabled globally.

huangapple
  • 本文由 发表于 2023年2月27日 16:03:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/75578012.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定