Bean Validation API 中 javax.validation.Payload 的用例是什么?

What is the use case of javax.validation.Payload in Bean Validation API?

Bean Validation specification 定义:

Constraint annotations must define a payload element that specifies the payload with which the constraint declaration is associated. The type of the payload parameter is Payload[].

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

The default value must be an empty array.
Each attachable payload extends Payload.

/**
 * Payload type that can be attached to a given
 * constraint declaration.
 * <p/>
 * Payloads are typically used to carry on metadata information
 * consumed by a validation client.
 * </p>
 * Use of payloads is not considered portable.
 */

我已经阅读了它的示例,但我不明白,例如,如何在 JSF 中使用此元数据?你能解释一下现实世界中有效载荷的其他用例吗? payload携带的元数据是什么?

也许这个link会对你有所帮助。


import javax.validation.*;
import javax.validation.constraints.NotNull;
import java.util.Set;

public class ConstraintPayloadExample2 {
    private static final Validator validator;

    static {
        Configuration<?> config = Validation.byDefaultProvider().configure();
        ValidatorFactory factory = config.buildValidatorFactory();
        validator = factory.getValidator();
        factory.close();
    }

    public interface AppErrorHandler<T> extends Payload {
        void onError (ConstraintViolation<T> violation);
    }

    public static class ErrorEmailSender<T> implements AppErrorHandler<T> {
        @Override
        public void onError (ConstraintViolation<T> violation) {
            System.out.println("Sending email to support team: " +
                                violation.getPropertyPath() + " " +
                                violation.getMessage());
        }
    }

    public static class TestBean {

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

        public String getStr () {
            return str;
        }

        public void setStr (String str) {
            this.str = str;
        }
    }

    public static void main (String[] args) {
        TestBean bean = new TestBean();

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

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


    private static void processError (ConstraintViolation<TestBean> violation) {
        Set<Class<? extends Payload>> payload =
                            violation.getConstraintDescriptor().getPayload();

        payload.forEach(p -> {
            if (AppErrorHandler.class.isAssignableFrom(p)) {
                try {
                    AppErrorHandler errorHandler = (AppErrorHandler) p.newInstance();
                    errorHandler.onError(violation);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}