Kiedy mam następujący model z JSR-303 (ramowej walidacja) Objaśnienia:wiążące Wiosna Boot i obsługi błędów walidacji w kontrolerze REST
public enum Gender {
MALE, FEMALE
}
public class Profile {
private Gender gender;
@NotNull
private String name;
...
}
i następujących danych JSON:
{ "gender":"INVALID_INPUT" }
W mój kontroler REST, chcę obsłużyć zarówno błędy wiązania (nieprawidłową wartość wyliczenia dla właściwości gender
), jak i błędy sprawdzania poprawności (name
właściwość nie może być pusta).
Poniższa metoda kontroler nie działa:
@RequestMapping(method = RequestMethod.POST)
public Profile insert(@Validated @RequestBody Profile profile, BindingResult result) {
...
}
Daje com.fasterxml.jackson.databind.exc.InvalidFormatException
błąd serializacji przed związaniem lub walidacja odbywa.
Po pewnym fiddling, wymyśliłem tego kodu niestandardowego, który robi to, co chcę:
@RequestMapping(method = RequestMethod.POST)
public Profile insert(@RequestBody Map values) throws BindException {
Profile profile = new Profile();
DataBinder binder = new DataBinder(profile);
binder.bind(new MutablePropertyValues(values));
// validator is instance of LocalValidatorFactoryBean class
binder.setValidator(validator);
binder.validate();
// throws BindException if there are binding/validation
// errors, exception is handled using @ControllerAdvice.
binder.close();
// No binding/validation errors, profile is populated
// with request values.
...
}
Zasadniczo co ten kod robi, jest serializacji do rodzajowego mapie zamiast modelu, a następnie użyć niestandardowego kodu do związania modelować i sprawdzać błędy.
Mam następujące pytania:
- Czy niestandardowy kod do zrobienia tu lub tam jest bardziej standardowy sposób w ten sposób w Spring Boot?
- Jak działa adnotacja ? Jak mogę utworzyć własną adnotację, która działa tak, jak
@Validated
, aby hermetyzować mój niestandardowy kod wiążący?
wadą jest to, że nie dostaniesz BindingResult gdy wystąpi błąd wiążące. To znaczy. możesz zrobić 'ex.getBindingResult()' w wyjątku 'MethodArgumentNotValidException', ale nie w wyjątku' HttpMessageNotReadableException'. –
Ten ostatni wydaje się rozsądny, ponieważ gdy wiązanie się nie powiedzie, nie moglibyśmy uzyskać wiążącego wyniku. Nie ma wiązania. –
W moim widoku błędy wiązania, takie jak wstawianie ciągu znaków w polu int lub błędna wartość wyliczenia, powinny być traktowane jako błędy sprawdzania poprawności. Korzystanie z autonomicznych "bindów danych" również wiąże pola w "BindingResult", dzięki czemu usługa może zwrócić bardziej szczegółową odpowiedź błędu. –