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

Spring中@RequestBody字符串参数自定义校验注解不生效问题咨询

问题描述

我编写了一个接收String类型@RequestBody参数的简单Controller,但val参数并未通过自定义校验器TestConstraintValidator进行校验,相关代码如下:

Controller代码

@RequestMapping(value = "/test", method = RequestMethod.POST)
public ResponseEntity doSmth(@RequestBody @ValidTest String val) {

    //do something
    return ResponseEntity
            .status(HttpStatus.OK)
            .body("saved");
}

自定义校验注解ValidTest代码

@Documented
@Constraint(validatedBy = TestConstraintValidator.class)
@Target({PARAMETER})
@Retention(RUNTIME)
public @interface ValidTest{
    String message() default "Invalid";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

校验器实现类代码

public class TestConstraintValidator implements ConstraintValidator<ValidTest, String> {
    @Override
    public void initialize(ValidTest constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
    }

    @Override
    public boolean isValid(String val, ConstraintValidatorContext constraintValidatorContext) {
       
        return false;
    }
}

请问是否可以直接对该参数进行校验?还是必须将String包装在自定义类中才能完成校验?


解答

可以直接对String类型的@RequestBody参数进行校验,不需要包装到自定义类中。你的校验未生效是因为缺少关键配置,修复步骤如下:

  1. 给Controller类添加@Validated注解
    Spring的参数级校验(直接标注在方法参数上的校验注解)需要通过@Validated触发,@Valid主要用于校验对象内部的字段。如果Controller没有该注解,Spring不会执行参数上的校验逻辑。修改后的Controller示例:

    @RestController
    @Validated // 必须添加此注解
    public class TestController {
    
        @RequestMapping(value = "/test", method = RequestMethod.POST)
        public ResponseEntity doSmth(@RequestBody @ValidTest String val) {
            //do something
            return ResponseEntity
                    .status(HttpStatus.OK)
                    .body("saved");
        }
    }
    
  2. 确认校验器逻辑正确
    你的TestConstraintValidator中isValid方法直接返回false,只要校验触发就会抛出校验异常。完成第一步配置后,该方法会被正常调用。

可选:添加全局异常处理器

如果需要统一处理校验失败的异常,可以添加全局异常处理器捕获ConstraintViolationException,返回自定义错误响应:

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<List<String>> handleConstraintViolation(ConstraintViolationException ex) {
        List<String> errorMessages = ex.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.toList());
        return ResponseEntity.badRequest().body(errorMessages);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:01:08