[SPRING] 여러 필드가있는 사용자 정의 주석 유효성 검사
SPRING여러 필드가있는 사용자 정의 주석 유효성 검사
조금 욕심 많은 질문이 있습니다.이 주석이 주석 유효성 검사에 대해 더 알고 싶은 사람들에게도 도움이되기를 바랍니다.
저는 현재 Spring을 연구 중입니다. 현재는 주석이 달린 검증을 맞춤화해볼 계획입니다.
필자는 많은 검색을 해왔고 이제는 주로 두 종류의 유효성 검사가 있다는 것을 알고 있습니다. 하나는 컨트롤러에 사용되고 다른 하나는 @Valid를 사용하는 주석 메서드입니다.
여기 내 시나리오가 있습니다. 두 개 이상의 필드가 있고 모두 NULL 일 때 null이 될 수 있다고 가정합니다. 그러나 빈 문자열을 제외한 값이 필드 중 하나에 포함되어있는 경우에만 해당 필드에 입력해야합니다. 그리고 두 가지 아이디어가 있지만 올바르게 구현하는 방법을 알지 못했습니다.
다음은 클래스 예제입니다.
public class Subscriber {
private String name;
private String email;
private Integer age;
private String phone;
private Gender gender;
private Date birthday;
private Date confirmBirthday;
private String birthdayMessage;
private Boolean receiveNewsletter;
//Getter and Setter
}
birthday 필드와 confirmBirthday 필드가 모두 null이거나 반대가 될 필요가 있다고 가정하면, 각각에 대해 하나의 주석을 사용하여 주석을 달고 다음과 같이 보일 수 있습니다.
public class Subscriber {
private String name;
private String email;
private Integer age;
private String phone;
private Gender gender;
@NotNullIf(fieldName="confirmBirthday")
private Date birthday;
@NotNullIf(fieldName="birthday")
private Date confirmBirthday;
private String birthdayMessage;
private Boolean receiveNewsletter;
//Getter and Setter
}
그래서 나는 이렇게 유효성 검사 Annotation을 만들어야한다 :
@Documented
@Constraint(validatedBy = NotNullIfConstraintValidator.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD })
public @interface NotNullIf {
String fieldName();
String message() default "{NotNullIf.message}";
Class<?>[] group() default {};
Class<? extends Payload>[] payload() default {};
}
그리고 나서 Validator 자체를 만들어야합니다.
public class NotNullIfConstraintValidator implements ConstraintValidator<NotNullIf, String>{
private String fieldName;
public void initialize(NotNullIf constraintAnnotation) {
fieldName = constraintAnnotation.fieldName();
}
public boolean isValid(String value, ConstraintValidatorContext context) {
if(value == null) {
return true;
};
//TODO Validation
return false;
}
}
동일한 클래스를 사용하여 생일을 원한다고 말한 또 다른 아이디어의 경우 confirmBirthday와 birthdayMessdage는 null이거나 동시에 반대 일 수 있습니다. 이번에는 교차 필드 유효성 검사를 위해 클래스 주석이 적용된 유효성 검사를 사용해야 할 수도 있습니다.
다음은 클래스에 주석을 추가하는 방법입니다.
@NotNullIf(fieldName={"birthday", "confirmBirthday", "birthdayMessage"})
public class Subscriber {
//Those field same as the above one
}
따라서 해당 필드 중 하나가 null이 아닌 경우 나머지는 또한 클라이언트 크기로 입력해야합니다. 가능한가?
이 기사를 읽었습니다 : 주석 속성에 설명 된 필드에 액세스하는 방법
그러나 위에 나열된 요소에서 주석 유효성 검사가 어떻게 작동하는지 아직도 혼란 스럽습니다. 어쩌면 그 코드에 대한 자세한 설명이 필요하거나 더 나쁘게 기본 개념 검사가 필요할 수도 있습니다.
도와주세요!
해결법
-
==============================
1.이를 위해 필드 레벨 주석에 다른 필드에 대한 액세스 권한이 없기 때문에 유형 레벨 주석 만 사용할 수 있습니다!
이를 위해 필드 레벨 주석에 다른 필드에 대한 액세스 권한이 없기 때문에 유형 레벨 주석 만 사용할 수 있습니다!
선택 유효성 검사를 허용하는 것과 비슷한 작업을 수행했습니다 (정확히 여러 속성 중 하나가 null이 아니어야 함). 귀하의 경우 @AllOrNone 주석 (또는 선호하는 이름)은 필드 이름의 배열을 필요로하고 주석 처리 된 유형의 전체 객체를 유효성 검사기로 가져옵니다.
@Target(ElementType.TYPE) @Retention(RUNTIME) @Documented @Constraint(validatedBy = AllOrNoneValidator.class) public @interface AllOrNone { String[] value(); String message() default "{AllOrNone.message}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } public class AllOrNoneValidator implements ConstraintValidator<AllOrNone, Object> { private static final SpelExpressionParser PARSER = new SpelExpressionParser(); private String[] fields; @Override public void initialize(AllOrNone constraintAnnotation) { fields = constraintAnnotation.value(); } @Override public boolean isValid(Object value, ConstraintValidatorContext context) { long notNull = Stream.of(fields) .map(field -> PARSER.parseExpression(field).getValue(value)) .filter(Objects::nonNull) .count(); return notNull == 0 || notNull == fields.length; } }
(스프링을 사용한다고 말했듯이 SpEL을 사용하여 중첩 된 필드에 액세스 할 수도있었습니다)
이제 구독자 유형에 주석을 달 수 있습니다.
@AllOrNone({"birthday", "confirmBirthday"}) public class Subscriber { private String name; private String email; private Integer age; private String phone; private Gender gender; private Date birthday; private Date confirmBirthday; private String birthdayMessage; private Boolean receiveNewsletter; }
from https://stackoverflow.com/questions/40353638/spring-custom-annotation-validation-with-multiple-field by cc-by-sa and MIT license