Spring MockMVC测试POST请求时出现415媒体类型不支持错误
我有一个用于创建实体的REST POST接口,使用MockMVC测试时,每次请求都返回415状态码(媒体类型不支持),错误信息如下:
java.lang.AssertionError: Status expected:<201> but was:<415> Expected :201 Actual :415
接口接收JSON格式请求体,MockMVC中已设置contentType为APPLICATION_JSON_VALUE,并通过Jackson序列化对象作为请求内容。
控制器受Spring Security过滤器管理,但已使用@AutoConfigureMockMvc(addFilters = false),且415是媒体类型问题,排除安全相关原因。
尝试过在控制器或测试配置类添加@EnableWebMvc,也试过切换MediaType.APPLICATION_JSON和MediaType.APPLICATION_JSON_VALUE,均无效。
相关代码如下:
测试配置类
@TestConfiguration @EnableWebMvc public class ProdutoControllerConfigurationTest { @Bean public ProdutoController produtoController() { return new ProdutoController(/* dependencies by autowired */); } }
DTO类
public class CriarProdutoDTO { @NotNull @Size(min = 2) @JsonProperty("nome_produto") private final String nomeProduto; @DecimalMin("0.1") private final BigDecimal preco; private final String descricao; @NotNull @Min(0) @JsonProperty("quantidade_estoque") private final Integer quantidadeEstoque; @NotNull @Min(1) @JsonProperty("categoria_id") private final Integer categoriaId; public CriarProdutoDTO(String nomeProduto, BigDecimal preco, String descricao, Integer quantidadeEstoque, Integer categoriaId) { this.nomeProduto = nomeProduto; this.preco = preco; this.descricao = descricao; this.quantidadeEstoque = quantidadeEstoque; this.categoriaId = categoriaId; } }
测试代码
@ActiveProfiles("testes") @ExtendWith(SpringExtension.class) @SpringBootTest @WebAppConfiguration @AutoConfigureMockMvc(addFilters = false) @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) public class ProdutoControllerTest { @Autowired private MockMvc mockMvc; @Autowired private ObjectMapper objectMapper; @Test public void deveRetornarCreated_criacaoProdutoSucesso() throws Exception { CriarProdutoDTO criarProdutoDTO = new CriarProdutoDTO("Nome", new BigDecimal("2.0"), "DESCRIÇÃO", 2, 1); mockMvc.perform(MockMvcRequestBuilders.post("/api/produtos") .contentType(MediaType.APPLICATION_JSON_VALUE) .content(objectMapper.writeValueAsString(criarProdutoDTO))) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isCreated()); } }
控制器代码
@RestController @RequestMapping(value = "/api/produtos") public class ProdutoController { @Autowired private ProdutoService produtoService; @Autowired private CriarProdutoDtoToProdutoConverter produtoConverter; @PostMapping @ResponseStatus(HttpStatus.CREATED) public void cadastrar(@RequestBody @Valid CriarProdutoDTO produtoDTO) { Produto novoProduto = produtoConverter.converter(produtoDTO); produtoService.cadastrar(novoProduto); } }
针对415媒体类型不支持的问题,可按以下步骤排查修复:
修复DTO的Jackson反序列化支持:
你的CriarProdutoDTO只有全参构造器,Jackson默认需要无参构造器或配合@ConstructorProperties注解完成JSON反序列化。可以给全参构造器添加注解:@ConstructorProperties({"nomeProduto", "preco", "descricao", "quantidadeEstoque", "categoriaId"}) public CriarProdutoDTO(String nomeProduto, BigDecimal preco, String descricao, Integer quantidadeEstoque, Integer categoriaId) { this.nomeProduto = nomeProduto; this.preco = preco; this.descricao = descricao; this.quantidadeEstoque = quantidadeEstoque; this.categoriaId = categoriaId; }若允许,也可以给DTO添加无参构造器(注意final成员变量需要调整为非final,或改用Builder模式)。
移除测试配置类的
@EnableWebMvc:@EnableWebMvc会覆盖Spring Boot的自动配置,可能导致消息转换器配置异常。删除ProdutoControllerConfigurationTest中的@EnableWebMvc注解,依赖Spring Boot默认的Web配置即可。添加Accept请求头:
虽然设置了contentType,但服务器可能期望特定的Accept头,在MockMVC请求中补充该配置:mockMvc.perform(MockMvcRequestBuilders.post("/api/produtos") .contentType(MediaType.APPLICATION_JSON_VALUE) .accept(MediaType.APPLICATION_JSON_VALUE) .content(objectMapper.writeValueAsString(criarProdutoDTO))) .andDo(MockMvcResultHandlers.print()) .andExpect(MockMvcResultMatchers.status().isCreated());验证Jackson依赖完整性:
确保项目依赖spring-boot-starter-web(默认包含Jackson相关组件),若单独引入Jackson,确认jackson-databind、jackson-annotations等依赖版本匹配。检查JSON序列化结果:
在测试中打印序列化后的JSON字符串,确认键名与DTO的@JsonProperty注解匹配:String json = objectMapper.writeValueAsString(criarProdutoDTO); System.out.println(json);
内容的提问来源于stack exchange,提问作者Victor Hugo Pongolino

