Я хочу сделать небольшую пользовательскую проверку с помощью JSR-303 javax.validation
.
У меня есть поле. И если в это поле вводится определенное значение, я хочу потребовать, чтобы некоторые другие поля не использовались null
.
Я пытаюсь понять это. Не знаю, как бы я это назвал, чтобы найти объяснение.
Любая помощь будет оценена. Я новичок в этом.
На данный момент я думаю о пользовательском ограничении. Но я не уверен, как проверить значение зависимого поля из аннотации. В основном я не уверен, как получить доступ к объекту панели из аннотации.
public class StatusValidator implements ConstraintValidator<NotNull, String> {
@Override
public void initialize(NotNull constraintAnnotation) {}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if ("Canceled".equals(panel.status.getValue())) {
if (value != null) {
return true;
}
} else {
return false;
}
}
}
Это panel.status.getValue();
доставляет мне неприятности .. не знаю, как это сделать.
Object
). В этом случае вам даже не нужно использовать отражение для получения значений, но в этом случае валидатор становится менее универсальным 2) использованиеBeanWrapperImp
из Spring Framework (или других библиотек) и егоgetPropertyValue()
метода. В этом случае вы сможете получить значение какObject
и привести к любому нужному типу.Определите метод, который должен подтверждаться как истинный, и поместите
@AssertTrue
аннотацию поверх него:@AssertTrue private boolean isOk() { return someField != something || otherField != null; }
Метод должен начинаться с "is".
источник
@AssertTrue(message="La reference doit etre un URL") public boolean isReferenceOk() { return origine!=Origine.Evolution||reference.contains("http://jira.bcaexpertise.org"); }
И это в моем jsp:<th><form:label path="reference"><s:message code="reference"/></form:label></th><td><form:input path="reference" cssErrorClass="errorField"/><br/><form:errors path="isReferenceOk" cssClass="error"/></td>
Но выдает ошибку.Вы должны использовать обычай
DefaultGroupSequenceProvider<T>
:ConditionalValidation.java
// Marker interface public interface ConditionalValidation {}
MyCustomFormSequenceProvider.java
public class MyCustomFormSequenceProvider implements DefaultGroupSequenceProvider<MyCustomForm> { @Override public List<Class<?>> getValidationGroups(MyCustomForm myCustomForm) { List<Class<?>> sequence = new ArrayList<>(); // Apply all validation rules from ConditionalValidation group // only if someField has given value if ("some value".equals(myCustomForm.getSomeField())) { sequence.add(ConditionalValidation.class); } // Apply all validation rules from default group sequence.add(MyCustomForm.class); return sequence; } }
MyCustomForm.java
@GroupSequenceProvider(MyCustomFormSequenceProvider.class) public class MyCustomForm { private String someField; @NotEmpty(groups = ConditionalValidation.class) private String fieldTwo; @NotEmpty(groups = ConditionalValidation.class) private String fieldThree; @NotEmpty private String fieldAlwaysValidated; // getters, setters omitted }
См. Также связанный вопрос по этой теме .
источник
getValidationGroups(MyCustomForm myCustomForm)
метод не передается ни один объект . Не могли бы вы здесь помочь? : stackoverflow.com/questions/44520306/…Вот мой взгляд на это, я постарался сделать это как можно проще.
Интерфейс:
@Target({TYPE, ANNOTATION_TYPE}) @Retention(RUNTIME) @Constraint(validatedBy = OneOfValidator.class) @Documented public @interface OneOf { String message() default "{one.of.message}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; String[] value(); }
Реализация валидации:
public class OneOfValidator implements ConstraintValidator<OneOf, Object> { private String[] fields; @Override public void initialize(OneOf annotation) { this.fields = annotation.value(); } @Override public boolean isValid(Object value, ConstraintValidatorContext context) { BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(value); int matches = countNumberOfMatches(wrapper); if (matches > 1) { setValidationErrorMessage(context, "one.of.too.many.matches.message"); return false; } else if (matches == 0) { setValidationErrorMessage(context, "one.of.no.matches.message"); return false; } return true; } private int countNumberOfMatches(BeanWrapper wrapper) { int matches = 0; for (String field : fields) { Object value = wrapper.getPropertyValue(field); boolean isPresent = detectOptionalValue(value); if (value != null && isPresent) { matches++; } } return matches; } private boolean detectOptionalValue(Object value) { if (value instanceof Optional) { return ((Optional) value).isPresent(); } return true; } private void setValidationErrorMessage(ConstraintValidatorContext context, String template) { context.disableDefaultConstraintViolation(); context .buildConstraintViolationWithTemplate("{" + template + "}") .addConstraintViolation(); } }
Применение:
@OneOf({"stateType", "modeType"}) public class OneOfValidatorTestClass { private StateType stateType; private ModeType modeType; }
Сообщения:
источник
Другой подход - создать (защищенный) получатель, который возвращает объект, содержащий все зависимые поля. Пример:
public class MyBean { protected String status; protected String name; @StatusAndSomethingValidator protected StatusAndSomething getStatusAndName() { return new StatusAndSomething(status,name); } }
StatusAndSomethingValidator теперь может получить доступ к StatusAndSomething.status и StatusAndSomething.something и выполнить зависимую проверку.
источник
Образец ниже:
package io.quee.sample.javax; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import javax.validation.ConstraintViolation; import javax.validation.Valid; import javax.validation.Validator; import javax.validation.constraints.Pattern; import java.util.Set; /** * Created By [**Ibrahim Al-Tamimi **](https://www.linkedin.com/in/iloom/) * Created At **Wednesday **23**, September 2020** */ @SpringBootApplication public class SampleJavaXValidation implements CommandLineRunner { private final Validator validator; public SampleJavaXValidation(Validator validator) { this.validator = validator; } public static void main(String[] args) { SpringApplication.run(SampleJavaXValidation.class, args); } @Override public void run(String... args) throws Exception { Set<ConstraintViolation<SampleDataCls>> validate = validator.validate(new SampleDataCls(SampleTypes.TYPE_A, null, null)); System.out.println(validate); } public enum SampleTypes { TYPE_A, TYPE_B; } @Valid public static class SampleDataCls { private final SampleTypes type; private final String valueA; private final String valueB; public SampleDataCls(SampleTypes type, String valueA, String valueB) { this.type = type; this.valueA = valueA; this.valueB = valueB; } public SampleTypes getType() { return type; } public String getValueA() { return valueA; } public String getValueB() { return valueB; } @Pattern(regexp = "TRUE") public String getConditionalValueA() { if (type.equals(SampleTypes.TYPE_A)) { return valueA != null ? "TRUE" : ""; } return "TRUE"; } @Pattern(regexp = "TRUE") public String getConditionalValueB() { if (type.equals(SampleTypes.TYPE_B)) { return valueB != null ? "TRUE" : ""; } return "TRUE"; } } }
источник