Spring无法校验JSON请求类型,如何仅接受字符串类型name参数?
解决方案
1. 强制Jackson严格类型检查,禁止数字转字符串
Jackson默认会自动将数字、布尔值等类型转换为字符串,导致@NotBlank校验无法拦截非字符串输入。需要开启FAIL_ON_NUMBERS_FOR_STRINGS特性,让Jackson在遇到数字转字符串时直接抛出异常,返回400错误。
配置方式二选一:
- 通过配置类:
@Configuration public class JacksonConfiguration { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); // 开启数字转字符串时抛出异常 mapper.enable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_STRINGS); return mapper; } }
- 通过配置文件:
# application.properties spring.jackson.deserialization.fail-on-numbers-for-strings=true
# application.yml spring: jackson: deserialization: fail-on-numbers-for-strings: true
2. 修复实体类的校验注解
字段上的@Valid是多余的,它用于嵌套对象的校验,单个String字段无需该注解。保留@NotBlank即可,它会同时校验字段不为null和去掉首尾空格后长度大于0:
@JsonProperty("name") @NotBlank(message = "name不能为空且不能为空白字符串") private String name;
3. 确保校验框架生效
Spring Boot 2.3及以上版本需手动引入校验依赖,否则@Valid和JSR-380注解不会生效:
<!-- pom.xml --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
// build.gradle implementation 'org.springframework.boot:spring-boot-starter-validation'
4. 全局异常处理(可选但推荐)
添加全局异常处理器统一返回格式,捕获类型转换和校验失败的异常:
@RestControllerAdvice public class GlobalExceptionHandler { // 捕获Jackson类型转换异常(如数字转字符串) @ExceptionHandler(JsonMappingException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleJsonMappingException(JsonMappingException e) { return "请求参数类型错误:" + e.getMessage(); } // 捕获校验失败异常 @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public String handleValidationException(MethodArgumentNotValidException e) { return e.getBindingResult().getFieldErrors().stream() .map(error -> error.getField() + ": " + error.getDefaultMessage()) .collect(Collectors.joining(", ")); } }
配置完成后:
- 传入
name:5时,Jackson抛出类型转换异常,返回400错误; - 传入
name:null或name:""时,@NotBlank触发校验失败,返回400错误; - 仅传入合法非空白字符串时,才能通过校验进入控制器方法。
内容的提问来源于stack exchange,提问作者Tom1998
相关产品推荐
相关产品推荐

