You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring MockMvc忽略未知字段无法触发@Valid校验如何解决

问题本质

你遇到的现象由两个核心原因导致:

  • 未知字段拦截不是@Valid注解提供的能力,是Jackson反序列化组件的DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES特性开启后,遇到请求体中不存在于接收类的字段时直接抛出异常的效果
  • 你使用standaloneSetup方式构建的MockMvc属于轻量化测试环境,不会自动加载项目中全局配置的Jackson参数,也不会自动注册JSR-380校验器,因此会出现和实际运行环境不一致的表现

解决步骤

1. 手动配置Jackson消息转换器

自定义MappingJackson2HttpMessageConverter,开启未知字段报错的特性,注册到MockMvc环境中。

2. 手动注册校验器

确保@Valid注解的参数校验逻辑正常生效。

修改后的测试代码示例:

import com.fasterxml.jackson.databind.DeserializationFeature;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

// 构造请求
MockHttpServletRequestBuilder builder = MockMvcRequestBuilders
        .post("/path" )
        .content("{\"fakeField\":\"fake\",\"userId\":\"clientId\"}")
        .contentType(MediaType.APPLICATION_JSON_VALUE);

String responseMessage = "Error message";

// 自定义Jackson转换器,开启未知字段拦截
MappingJackson2HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter();
jacksonConverter.getObjectMapper().enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

// 初始化校验器
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
validator.afterPropertiesSet();

// 构建MockMvc时注入自定义配置
this.mockMvc = standaloneSetup(myController)
        .setMessageConverters(jacksonConverter)
        .setValidator(validator)
        .build();

// 执行测试
this.mockMvc
        .perform(builder)
        .andDo(print())
        .andExpect(status().is(HttpStatus.BAD_REQUEST.value()))
        .andExpect(content().string(containsString(responseMessage)));

注意事项

如果你的RequestClass类上标注了@JsonIgnoreProperties(ignoreUnknown = true),会覆盖全局Jackson配置,此时即使开启了FAIL_ON_UNKNOWN_PROPERTIES也不会拦截未知字段,需要移除该注解或者将ignoreUnknown属性设为false。


内容的提问来源于stack exchange,提问作者Tilmiz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:15:03