【问题标题】:Controller returning inputstream - content negotiation and media types控制器返回输入流 - 内容协商和媒体类型
【发布时间】:2018-07-27 12:04:27
【问题描述】:

简介

我有一个关于 RestController 和 Test 的问题。

我有以下PostMapping

@PostMapping(path = "/download/as/zip/{zipFileName}" )
    @ResponseBody
    public ResponseEntity<InputStreamResource> downloadDocumentZip(@RequestHeader(required=false,name="X-Application") String appName, @RequestBody ZipFileModel zipFileModel, @PathVariable("zipFileName") String zipFileName)

我有以下测试:

Response response = given(this.requestSpecification).port(port)
                .filter(document("downloadAsZip",
                        preprocessRequest(prettyPrint()),
                        requestHeaders(headerWithName("X-Application").description("Owner application")),
                        pathParameters(parameterWithName("zipFileName").description("The name of the resulting zip file. Mostly not needed/optional.")))
                )
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .header(new Header(HEADER, "themis"))
                .body(jsonContent)
                .when()
                .post("/download/as/zip/{zipFileName}", "resultFile.zip");

这有效,返回 200。

第一个问题

现在我对测试中.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE) 的含义有些困惑。

Content-type 是返回响应的标头。但是在这个测试中,它在发出测试请求时被包括在内吗? 或者在这种情况下,是否表示我们在请求正文中发送 JSON?

第二个问题

我知道我的控制器方法应该使用 JSON,并返回字节。 因此,我进行了以下更改:

@PostMapping(path = "/download/as/zip/{zipFileName}", 消耗 = MediaType.APPLICATION_JSON_VALUE)

到目前为止有效。

然后我添加以下内容:

@PostMapping(path = "/download/as/zip/{zipFileName}", consumes = MediaType.APPLICATION_JSON_VALUE, 
produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)

它失败了:

java.lang.AssertionError: 
Expected :200
Actual   :406
 <Click to see difference>

所以我将测试更改为以下内容:

.contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
                .accept(MediaType.APPLICATION_OCTET_STREAM_VALUE)

这又失败了。

Expected :200
Actual   :406

因此,即使客户端发出与控制器生成的相同的接受标头,我们还是有错误。

问题:

  1. 那么我们是否应该在请求映射中使用produces=
  2. 为什么现在失败了?消费 JSON 和生产字节有冲突吗?还是测试中的ContentType

【问题讨论】:

    标签: spring request-mapping content-negotiation


    【解决方案1】:

    问题在于,如果 URL 的末尾有扩展名,spring 会更改返回内容类型。

    所以最后看到 .zip 导致 spring 将类型覆盖为 application/zip 。

    【讨论】:

      猜你喜欢
      • 2014-11-15
      • 2012-07-07
      • 1970-01-01
      • 2016-01-05
      • 2015-08-06
      • 2014-02-23
      • 1970-01-01
      • 2012-12-04
      • 2021-07-11
      相关资源
      最近更新 更多