我想在Json请求中验证Maps列表和Maps中的键。 但是如何为List中的泛型Map添加自定义注释? 请看下面的代码。
当我这样尝试时,不会执行CheckKeysMapValidator类。
------- JSON请求的一部分-------
"attributes": [{
"name": "Chandra",
"address": "India"
},
{ "name": "Sam",
"address": "US"
},
{
"name": "David",
"address": "England"
}
],
------------模型类----------
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;
}
}