首页 > 解决方案 > 从 POST 获取 415 错误以下载文件

问题描述

我正在使用 Spring Rest 下载一个 zip 文件,然后其内容由文档 ID 列表确定。

我的控制器是这样的

@RestController
@RequestMapping("api/zip-documents")
public class DocumentsRestController {
    
    @Autowired
    private DocumentDownloadService documentDownloadService;
    
    @PostMapping(produces = {"application/zip"}, consumes = {"application/json"})
    public ResponseEntity<Resource> downloadZip(@RequestBody List<String> documentIds) throws IOException {
        // Zip the documents into a file
        ByteArrayOutputStream outputStream = documentDownloadService.downloadZip(documentIds);
        ByteArrayResource resource = new ByteArrayResource(outputStream.toByteArray());
        return ResponseEntity.ok().header("Content-Disposition", "attachment; filename=\"file.zip\"")
            .contentLength(outputStream.size()).body(resource);
    }
}

我的测试,使用 Mockito 如下,我在运行应用程序时也遇到了同样的问题:

    @Test
    public void downloadZip_sunnyDayUseCase_contentTypeIsZip() throws Exception {
        Mockito.when(documentDownloadService.downloadZip(Matchers.anyListOf(String.class)))
            .thenReturn(new ByteArrayOutputStream());

        mockMvc
            .perform(post("/api/zip-documents")
                    .content("{ \"documentIds\": [\"123123\"] }"))
            .andExpect(status().isOk())
            .andExpect(content().contentType("application/zip"));
    }

我收到 HttpStatus 415 响应。这似乎是请求标头的问题,因为我无法在 restcontroler 中打断点。

标签: javaspringresthttp-headersfile-type

解决方案


HTTP 状态码415代表Unsupported Media Type. 由于您尝试将 JSON 数据发布到端点,因此您可能希望Content-Type: application/json在 POST 中的某处有一个标头。

因此,在您的 中mockMvc,我想尝试以下操作:

mockMvc
            .perform(post("/api/zip-documents")
                    .header("Content-Type", "application/json")
                    .content("{ \"documentIds\": [\"123123\"] }"))
            .andExpect(status().isOk())
            .andExpect(content().contentType("application/zip"));

推荐阅读