使用SpringBoot HttpRequestTest测试multipart/form-data时遇415错误
问题分析与修复方案
核心错误点
- 接口参数注解误用:在
multipart/form-data类型的请求中,不能用@RequestBody接收JSON参数。@RequestBody是用来解析整个请求体为指定格式的,但multipart请求由多个独立的part组成,每个part有自己的媒体类型,需用@RequestPart来单独解析JSON部分。 - 测试代码参数传递错误:
- 多余向请求body中添加
id参数(id是@PathVariable,只需从URL路径传递); - JSON参数未正确包装为带
application/json媒体类型的multipart part,导致Spring无法识别并解析。
- 多余向请求body中添加
修复步骤
1. 修改接口代码
将@RequestBody替换为@RequestPart,指定对应参数名(需和测试代码中的参数名一致):
@PostMapping(value = "/{id}", consumes = {"multipart/form-data"}) @ResponseStatus(code = HttpStatus.CREATED) public ResponseEntity<LocalizedStatusMessage> postFormFileUpload( @PathVariable(value = "id") String id, @RequestPart("content") Map<String, JsonNode> rawFormValues, @RequestParam("attachments") MultipartFile[] attachments) { // 原有业务逻辑 }
2. 修正测试代码
- 移除body中的
id参数; - 将JSON字符串包装为带
application/json头的HttpEntity,作为multipart的一个part传入; - 保留附件的正确处理逻辑:
@Autowired private TestRestTemplate restTemplate; public void givenMultipartFormData_whenEndpointIsCalled_thenReturn201() { String id = "fileTest"; String content = "{\"fileTestField\": []}"; MultipartFile[] attachments = new MultipartFile[]{}; HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap<String, Object> body = new LinkedMultiValueMap<>(); // 包装JSON参数,指定媒体类型为application/json HttpHeaders jsonPartHeaders = new HttpHeaders(); jsonPartHeaders.setContentType(MediaType.APPLICATION_JSON); HttpEntity<String> jsonPart = new HttpEntity<>(content, jsonPartHeaders); body.add("content", jsonPart); // 添加附件(空数组不影响,有文件时逻辑依然有效) for (MultipartFile attachment : attachments) { body.add("attachments", attachment.getResource()); } HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers); String url = domain + port + formPath + "/" + id; ResponseEntity<String> result = restTemplate.postForEntity(url, requestEntity, String.class); assertEquals(HttpStatus.CREATED, result.getStatusCode()); }
错误原因说明
415 UNSUPPORTED_MEDIA_TYPE错误的本质是:Spring无法识别请求中JSON参数的媒体类型。原接口用@RequestBody期望整个请求体是JSON,但实际发送的是multipart/form-data请求;测试代码中直接传入字符串形式的JSON,未指定该part的媒体类型,导致Spring无法解析为Map<String, JsonNode>类型。
内容的提问来源于stack exchange,提问作者Nivia
相关产品推荐
相关产品推荐

