控制器返回输入流-内容协商和媒体类型

时间:2018-07-27 12:04:28

标签: spring request-mapping content-negotiation

简介

我有一个关于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,并返回Bytes。 因此,我进行了以下更改:

@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

1 个答案:

答案 0 :(得分:0)

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

因此,最后看到.zip,是导致spring超越type到application / zip的原因。