如何在Spring Boot中添加基于条件的@NotNull约束?

问题描述 投票:0回答:1

我们正在使用

spring-boot
。 我想在java类中添加基于条件的约束。 例如

@Entity
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name = "user_id")
    private Integer userId;
    @Column(name = "firstName")
    private String firstName;
    @Column(name = "lastName")
    private String lastName;
}

现在在上面的代码中,当且仅当

@NotNull
属性不为空时,我想对
lastName
属性添加
firstName
约束。

spring-boot annotations
1个回答
0
投票

在这种情况下,您可以使用验证组和自定义约束验证器来实现条件验证。这是一个例子:

@Entity
public class User {
    ...

    @Column(name = "firstName")
    private String firstName;

    @ConditionalNotNull
    @Column(name = "lastName")
    private String lastName;

    ....
}

现在,定义ConditionalNotNull注释和相应的ConditionalNotNullValidator:

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ConditionalNotNullValidator.class)
public @interface ConditionalNotNull {
    String message() default "Field must not be null if the condition is met";

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

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

    String value() default "";
}

条件NotNull验证器:

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class ConditionalNotNullValidator implements ConstraintValidator<ConditionalNotNull, Object> {

    private String field;

    @Override
    public void initialize(ConditionalNotNull constraintAnnotation) {
        this.field = constraintAnnotation.value();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if (value == null) {
            return true; // Null values are accepted, let @NotNull handle it
        }

        try {
            // Use reflection to get the value of the condition field
            Object conditionFieldValue = value.getClass().getDeclaredMethod("get" + capitalize(field)).invoke(value);

            // Check the condition and validate accordingly
            return conditionFieldValue != null;
        } catch (Exception e) {
            throw new IllegalArgumentException("Error accessing condition field", e);
        }
    }

    private String capitalize(String s) {
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }
}

这样,如果firstName 字段不为空,那么lastName 字段将仅使用@NotNull 进行验证。如果firstName为空,则lastName被视为有效,无论其值如何。

© www.soinside.com 2019 - 2024. All rights reserved.