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

Spring Boot中如何创建带参数的自定义注解验证并按需传参?

Spring Boot带参数的自定义注解验证实现

1. 定义带参数的自定义注解

先创建自定义注解@ConcertValidation,通过注解属性传递参数,同时指定对应的验证器:

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Documented
@Constraint(validatedBy = ConcertValidationValidator.class)
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ConcertValidation {
    // 错误提示信息
    String message() default "验证不通过";

    // 分组验证用
    Class<?>[] groups() default {};

    // 负载信息
    Class<? extends Payload>[] payload() default {};

    // 自定义参数:更衣室类型
    String dressingRoom();
}

2. 实现带参数逻辑的验证器

实现ConstraintValidator接口,在initialize方法中获取注解传递的参数,在isValid方法中根据参数值执行不同的验证逻辑:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.List;
import java.util.Map;

public class ConcertValidationValidator implements ConstraintValidator<ConcertValidation, List<Map<String, String>>> {

    private String dressingRoom;

    // 初始化时获取注解的参数值
    @Override
    public void initialize(ConcertValidation constraintAnnotation) {
        this.dressingRoom = constraintAnnotation.dressingRoom();
    }

    @Override
    public boolean isValid(List<Map<String, String>> jsonList, ConstraintValidatorContext context) {
        if (jsonList == null || jsonList.isEmpty()) {
            return true; // 根据业务需求调整是否允许为空
        }

        // 根据注解参数分支处理验证逻辑
        if ("chill".equals(dressingRoom)) {
            for (Map<String, String> map : jsonList) {
                // 检查是否包含snack键
                if (!map.containsKey("snack")) {
                    context.disableDefaultConstraintViolation();
                    context.buildConstraintViolationWithTemplate("chill模式下必须包含snack字段")
                            .addConstraintViolation();
                    return false;
                }
                String snackValue = map.get("snack");
                // 验证snack值的长度
                if (snackValue == null || snackValue.length() < 1 || snackValue.length() > 10) {
                    context.disableDefaultConstraintViolation();
                    context.buildConstraintViolationWithTemplate("chill模式下snack长度必须在1-10之间")
                            .addConstraintViolation();
                    return false;
                }
            }
        }
        // 可扩展其他dressingRoom值的验证逻辑,比如"formal"模式规则
        // else if ("formal".equals(dressingRoom)) { ... }

        return true;
    }
}

3. 使用自定义注解

在需要验证的字段上添加注解并传递参数,同时在实体类或Controller方法参数上添加@Valid或@Validated触发验证:

import javax.validation.Valid;
import java.util.List;
import java.util.Map;

public class ConcertRequest {

    @ConcertValidation(dressingRoom = "chill")
    private List<Map<String, String>> json;

    // getter和setter
}

在Controller中使用:

import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Validated
public class ConcertController {

    @PostMapping("/concert")
    public String submitConcert(@Valid @RequestBody ConcertRequest request) {
        return "提交成功";
    }
}

关键说明

  • 自定义注解完全支持传递参数,通过注解的属性定义即可实现,比如示例中的dressingRoom参数。
  • 验证逻辑可以根据参数值动态调整,在isValid方法中通过判断参数分支执行不同的验证规则,可扩展性强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:25:21