如何在自定义约束注解的约束违规消息中显示字段名描述?

How do I display the field name description in the constraint violation message of a custom constraint annotation?

如何在 Bean Validation 1.1 (JSR-349) 自定义约束注释的约束违规消息中显示字段名称描述?

例如,给定以下自定义约束注释 @Required、资源包 ValidationMessages.properties 和 class Person,我如何编写约束违反消息“名字是必填项。”对于必填字段 firstName 和“姓氏是必填项。”对于必填字段 lastName

@Documented
@Constraint(validatedBy = {})
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@NotEmpty
@ReportAsSingleViolation
public @interface Required {
    public abstract Class<?>[] groups() default {};
    public abstract String message() default "{Required.message}";
    public abstract Class<? extends Payload>[] payload() default {};
}

在资源包中,ValidationMessages.properties:

Required.message=is required.

Class Person:

public class Person {
    @Required
    private String firstName;

    @Required
    private String lastName;
}

没有 API 可用于获取当前 属性 名称。如果有,您仍然需要进行一些字符串操作,以从 属性 名称 'firstName' 获取显示名称 "First Name".

也就是说,我可以看到在传递给 ConstraintValidator#isValidConstraintValidatorContext 中公开当前 Path 的好处。这是每个规范不可能的 atm,但它可以作为提供者特定的功能来实现。您可以为 Hibernate Validator here.

创建问题请求

关于你的问题,我认为最好的解决方案是添加一个'labelattribute to@Required`:

public class Person {
    @Required(label="First Name"
    private String firstName;

    @Required(label="Last Name"
    private String lastName;
}

然后您可以像这样在消息包中插入标签:

Required.message={label} is required.

约束看起来像这样

@Documented
@Constraint(validatedBy = {})
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@NotEmpty
@ReportAsSingleViolation
public @interface Required {
    public abstract String label();
    public abstract Class<?>[] groups() default {};
    public abstract String message() default "{Required.message}";
    public abstract Class<? extends Payload>[] payload() default {};
}

注意,可以添加自己喜欢的参数(前提是Java支持的参数类型)

ConstraintViolation constraintViolation .. ((PathImpl)constraintViolation.getPropertyPath()).getLeafNode().getName();