如果我想要像这样的发布请求定义:
@PostMapping(path = "/metadata/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ResponseEntity<Void> test(HttpServletResponse response,//
@RequestPart(value = "file") MultipartFile file,
@RequestPart(value = "partName") Metadata partName,
@PathVariable(name = "id") String artifactId) {
return null;
}
(其中元数据是一个简单的 Pojo) 然后使用以下测试:
@Test
public void testMetadata() throws Exception {
mockMvc
.perform(multipart(HttpMethod.POST, "/metadata/123")
.file("file", "file content".getBytes())
.part(getJsonPart())
.contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
.andExpect(status().isOk());
}
private @NotNull MockPart getJsonPart() throws JsonProcessingException {
byte[] partContent = new ObjectMapper().writeValueAsBytes(new Metadata("foo"));
MockPart part = new MockPart("partName", partContent);
part.getHeaders().setContentType(MediaType.APPLICATION_JSON);
return part;
}
它不匹配 - 我收到 400 响应而不是 200。我认为它无法反序列化有效负载。
但是,当我将后映射的零件类型从“元数据”更改为“对象”时,它就可以工作(将零件反序列化为地图)。
现在我可能对一些显而易见的事情视而不见,但显然我无法自己解决这个问题。有什么提示吗?只是重申一下:我想要得到的是一个具有正确反序列化“元数据”对象的控制器。
为了完整起见,这里有 2 个完整文件:
class Metadata {
private String value;
public Metadata(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
@RestController
public class TestController {
@PostMapping(path = "/metadata/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ResponseEntity<Void> test(HttpServletResponse response,//
@RequestPart(value = "file") MultipartFile file,
@RequestPart(value = "partName") Metadata partName,
@PathVariable(name = "id") String artifactId) {
return null;
}
@PostMapping(path = "/object/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
ResponseEntity<Void> test(HttpServletResponse response, @RequestPart(value = "file") MultipartFile file,
@RequestPart(value = "partName") Object partName,
@PathVariable(name = "id") String artifactId) {
return null;
}
}
@WebMvcTest(TestController.class)
public class TestControllerTest {
@Autowired
public MockMvc mockMvc;
@Test
public void failingTest() throws Exception {
mockMvc
.perform(multipart(HttpMethod.POST, "/metadata/123")
.file("file", "file content".getBytes())
.part(getJsonPart())
.contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
.andExpect(status().isOk());
}
@Test
public void passingTest() throws Exception {
mockMvc
.perform(multipart(HttpMethod.POST, "/object/123")
.file("file", "file content".getBytes())
.part(getJsonPart())
.contentType(MediaType.MULTIPART_FORM_DATA_VALUE))
.andExpect(status().isOk());
}
private @NotNull MockPart getJsonPart() throws JsonProcessingException {
byte[] partContent = new ObjectMapper().writeValueAsBytes(new Metadata("foo"));
MockPart part = new MockPart("partName", partContent);
part.getHeaders().setContentType(MediaType.APPLICATION_JSON);
return part;
}
}
呃,这太尴尬了...
问题是缺少无参构造函数,导致反序列化失败。但在这种情况下,解串器的错误消息会丢失并且不会出现。
所以,解决方案只是一个空的构造函数。