如何在Java8+;休眠验证器?

如何在Java8+;休眠验证器?,java,java-8,annotations,hibernate-validator,type-parameter,Java,Java 8,Annotations,Hibernate Validator,Type Parameter,我想在Json请求中验证映射和映射中的键的列表。 但如何在列表中为泛型类型映射添加自定义注释? 请看下面的代码 当我这样尝试时,不会执行CheckKeysMapValidator类 -------JSON请求的一部分------- ------------模范班---------- classrequestto{ @NotEmpty(message=“'attributes'是必需的。”) @有效的 私人列表属性; 公共列表getAttributes(){ 返回属性; } 公共void集合属性(

我想在Json请求中验证映射和映射中的键的列表。 但如何在列表中为泛型类型映射添加自定义注释? 请看下面的代码

当我这样尝试时,不会执行CheckKeysMapValidator类

-------JSON请求的一部分-------

------------模范班----------

classrequestto{
@NotEmpty(message=“'attributes'是必需的。”)
@有效的
私人列表<@CheckKeysForMap(
message=“'attributes'必须包含'name'和'address'两个属性。”,
值={“名称”,“地址”})映射>属性;
公共列表getAttributes(){
返回属性;
}
公共void集合属性(列表属性){
this.attributes=属性;
}
}
-------自定义注释-----------------

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.TYPE_PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.NotNull;

/**
 * Marks the Map property to check if Map contains defined keys or not.
 *
 */

@Target({ FIELD, PARAMETER, TYPE_USE, TYPE, TYPE_PARAMETER, LOCAL_VARIABLE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@NotNull
@Constraint(validatedBy = { CheckKeysMapValidator.class })
public @interface CheckKeysForMap {
    String message() ;
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
    String[] value() ;  

}
导入静态java.lang.annotation.ElementType.annotation\u类型;
导入静态java.lang.annotation.ElementType.FIELD;
导入静态java.lang.annotation.ElementType.LOCAL_变量;
导入静态java.lang.annotation.ElementType.PARAMETER;
导入静态java.lang.annotation.ElementType.TYPE;
导入静态java.lang.annotation.ElementType.TYPE_参数;
导入静态java.lang.annotation.ElementType.TYPE\u使用;
导入静态java.lang.annotation.RetentionPolicy.RUNTIME;
导入java.lang.annotation.Documented;
导入java.lang.annotation.Retention;
导入java.lang.annotation.Target;
导入javax.validation.Constraint;
导入javax.validation.Payload;
导入javax.validation.constraints.NotNull;
/**
*标记映射属性以检查映射是否包含已定义的键。
*
*/
@目标({字段、参数、类型\使用、类型、类型\参数、局部\变量、注释\类型})
@保留(运行时)
@记录
@NotNull
@约束(validatedBy={CheckKeysMapValidator.class})
public@interface CheckKeysForMap{
字符串消息();
类[]组()默认值{};
类别>{
字符串[]所需密钥;
字符串emptyString=“”;
@凌驾
公共无效初始化(CheckKeysForMap ConstraintAnotation){
requiredKeys=ConstraintAnotation.value();
}
@凌驾
公共布尔值有效(映射、约束验证或上下文上下文){
if(map.isEmpty()){
返回false;
}
for(字符串requiredKey:requiredKey){
requiredKey=requiredKey.toLowerCase();
Map lowerCaseMap=newtreemap(String.CASE不区分大小写\u顺序);
小写字母map.putAll(map);
如果(!lowerCaseMap.containsKey(requiredKey)| | lowerCaseMap.containsValue(emptyString)){
返回false;
}
}
返回true;
}
}

看到您实际如何进行验证也会很好。您是否可以添加该代码段?
 Class RequestTO{
    @NotEmpty(message = "'attributes' is required.")   
       @Valid
       private List< @CheckKeysForMap(
             message = "'attributes' must contain two properties as 'name' and 'address'.",
             value = { "name", "address" }) Map<String, String>> attributes;


              public List<Map<String, String>> getAttributes() {
          return attributes;
       }

       public void setAttributes(List<Map<String, String>> attributes) {
          this.attributes = attributes;
       }

    }
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.TYPE_PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.NotNull;

/**
 * Marks the Map property to check if Map contains defined keys or not.
 *
 */

@Target({ FIELD, PARAMETER, TYPE_USE, TYPE, TYPE_PARAMETER, LOCAL_VARIABLE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Documented
@NotNull
@Constraint(validatedBy = { CheckKeysMapValidator.class })
public @interface CheckKeysForMap {
    String message() ;
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
    String[] value() ;  

}
 import java.util.Map;
    import java.util.TreeMap;

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

    public class CheckKeysMapValidator implements ConstraintValidator<CheckKeysForMap, Map<String, ?>> {

       String[] requiredKeys;
       String emptyString = "";

       @Override
       public void initialize(CheckKeysForMap constraintAnnotation) {
          requiredKeys = constraintAnnotation.value();

       }

       @Override
       public boolean isValid(Map<String, ?> map, ConstraintValidatorContext context) {
          if (map.isEmpty()) {
             return false;
          }

          for (String requiredKey : requiredKeys) {
             requiredKey = requiredKey.toLowerCase();
             Map<String, Object> lowerCaseMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
             lowerCaseMap.putAll(map);
             if (!lowerCaseMap.containsKey(requiredKey) || lowerCaseMap.containsValue(emptyString)) {
                return false;
             }

          }
          return true;
       }

    }