Pytanie Ręczne wywołanie sprawdzania adnotacji wiosennej


Sprawdzam wiele z Hibernate i Adnotacjami wiosennymi:

public class Account {
    @NotEmpty(groups = {Step1.class, Step2.class})
    private String name;

    @NotNull(groups = {Step2.class})
    private Long accountNumber;

    public interface Step1{}
    public interface Step2{}
}

A potem w kontrolerze wywołuje się argumenty:

public String saveAccount(@ModelAttribute @Validated({Account.Step1.class}) Account account, BindingResult result) {
   //some more code and stuff here
   return "";
}

Ale chciałbym zdecydować, która grupa jest używana w oparciu o pewną logikę w metodzie sterownika. Czy istnieje sposób ręcznego sprawdzania poprawności? Coś jak result = account.validate(Account.Step1.class)?

Jestem świadomy tworzenia własnej klasy Validator, ale jest to coś, czego chcę uniknąć, wolałbym po prostu użyć adnotacji na samych zmiennych klas.


25
2017-10-04 20:51


pochodzenie




Odpowiedzi:


Idąc o krok dalej niż Jaiwo99 w swojej odpowiedzi:

// org.springframework.validation.SmartValidator - implemented by
//     LocalValidatorFactoryBean, which is funny as it is not a FactoryBean per se (just saying)
@Autowired
SmartValidator validator;

public String saveAccount(@ModelAttribute Account account, BindingResult result) {
    // ... custom logic
    validator.validate(account, result, Account.Step1.class);
    if (result.hasErrors()) {
        // ... on binding or validation errors
    } else {
        // ... on no errors
    }
    return "";
}

I obowiązkowy link do SmartValidator JavaDoc Jeśli jesteś zainteresowany.


33
2017-10-04 21:38



OP stwierdził, że nie chce tworzyć klasy Validator, ale wywoływać validator.validate(account, errors, Account.Step1.class) z osobnego walidatora wygodnie dodaje błędy do jednostki odpowiedzi (jeśli BindingResult nie jest zdefiniowany w kontrolerze). - Milanka


Oto przykład kodu z JSR 303 spec

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

Driver driver = new Driver();
driver.setAge(16);
Car porsche = new Car();
driver.setCar(porsche);


Set<ConstraintViolation<Driver>> violations = validator.validate( driver );

Więc tak, możesz po prostu pobrać instancję sprawdzania poprawności z fabryki walidatorów i samemu przeprowadzić walidację, a następnie sprawdzić, czy nie ma takich naruszeń, czy nie. Możesz zobaczyć w javadoc dla Validator że zaakceptuje również tablicę grup do sprawdzenia.

Oczywiście używa to sprawdzania poprawności JSR-303 bezpośrednio zamiast sprawdzania wiosennego, ale uważam, że wiosenne adnotacje sprawdzania poprawności użyją JSR-303, jeśli znajdzie się w ścieżce klas


13
2017-10-04 21:10



Chodzi o to, że jeśli używasz Spring MVC, prawdopodobnie chcesz BindingResult / Errors zamiast ConstraintViolations. Tak więc, podczas gdy twoja odpowiedź jest poprawna, nie nadaje się do tego pytania. - Pavel Horal


Jeśli wszystko jest poprawnie skonfigurowane, możesz to zrobić:

@Autowired
Validator validator;

Następnie możesz go użyć do sprawdzenia poprawności obiektu.


6
2017-10-04 21:25





I również:

@Autowired
@Qualifier("mvcValidator")
Validator validator;

...
violations = validator.validate(account);

1
2017-11-21 14:29