Java 中的自定义注释中的组和负载有什么用?

Enf*_*3rr 16 java spring annotations spring-mvc

这是我的代码,我尝试在线阅读很多内容,但无法理解实际使用

Class<?> [] groups() default{};
Class<? extends Payload>[] payload() default{};
Run Code Online (Sandbox Code Playgroud)

这是我使用它的代码。

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueValidator.class)
public @interface UniqueValue {
    String message() default "Unique Constraint Violated";
    
    Class<?> [] groups() default{};
    Class<? extends Payload>[] payload() default{};
}
Run Code Online (Sandbox Code Playgroud)

谢谢。

小智 15

组允许您限制验证期间应用的约束集。

在以下示例中,AClass类具有bool属于AGroup组的属性。但是当某个属性的组没有指定时,即 的其他属性的情况AClass,那么它就属于默认组javax.validation.groups.Default

import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;

public class AClass {

    @NotBlank
    private String string;

    @Min(2)
    private int integer;

    @AssertTrue(groups = AGroup.class)
    private boolean bool;

    public AClass(String string, int integer, boolean bool) {
        this.string = string;
        this.integer = integer;
        this.bool = bool;
    }
}
Run Code Online (Sandbox Code Playgroud)

组声明可以是一个简单的空接口。

public interface AGroup { }
Run Code Online (Sandbox Code Playgroud)

在以下程序中,该validate方法验证属于默认组的所有属性。但要验证其他组的属性,您必须在validate方法中指定将验证​​哪组属性。

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.junit.Assert;

public class Program {

    public static void main(String[] args) {
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

        // create a AClass and check that everything is ok with it.
        AClass a = new AClass("Foo", 2, false);
        Set<ConstraintViolation<AClass>> constraintViolations = validator.validate(a);
        Assert.assertEquals(0, constraintViolations.size());

        // but has it passed the bool field?
        constraintViolations = validator.validate(a, AGroup.class);
        Assert.assertEquals(1, constraintViolations.size());
        Assert.assertEquals("must be true", constraintViolations.iterator().next().getMessage()
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

来源:https://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html/ch05.html#example-driver

Bean Validation API 的客户端可以使用有效负载将自定义有效负载对象分配给约束。API 本身不使用此属性。

在以下示例中,该类TestBean具有一个带有 的属性Payload

import javax.validation.constraints.NotNull;

public class TestBean {

    @NotNull(payload = {ErrorEmailSender.class})
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }
}
Run Code Online (Sandbox Code Playgroud)

有效负载的实现ErrorEmailSender

import javax.validation.ConstraintViolation;
import javax.validation.Payload;

public class ErrorEmailSender implements Payload {

    public void onError(ConstraintViolation violation) {
        System.out.println("Sending email to support team: "
                + violation.getPropertyPath() + " "
                + violation.getMessage());
    }
}
Run Code Online (Sandbox Code Playgroud)

程序Client检查TestBean实例是否有效,如果无效,则调用Payload无效属性。

import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

public class Client {

    public static void main(String[] args) {
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

        TestBean bean = new TestBean();
        Set<ConstraintViolation<TestBean>> constraintViolations = validator.validate(bean);

        if (constraintViolations.size() > 0) {
            constraintViolations.stream().forEach(Client::processError);
        } else {
            //proceed using user object
            System.out.println(bean);
        }
    }

    private static void processError(ConstraintViolation<TestBean> violation) {
        violation.getConstraintDescriptor().getPayload().forEach(p -> {
            if (ErrorEmailSender.class.isAssignableFrom(p)) {
                try {
                    ((ErrorEmailSender) p.getDeclaredConstructor().newInstance()).onError(violation);
                } catch (Exception ex) {
                    System.out.println(ex);
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

您应该在输出中看到:

Sending email to support team: str must not be null
Run Code Online (Sandbox Code Playgroud)

资料来源: