• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zwracanie error kodu jako ResponseEntity po walidacji DTO w REST API

VPS Starter Arubacloud
0 głosów
478 wizyt
pytanie zadane 27 lipca 2017 w Java przez Jonki Dyskutant (8,180 p.)

Korzystając z poradnika https://www.leveluplunch.com/[...]ring-rest-webservice-request/ chcę dokonać walidacji formularza za pomocą java bez przeładowywania strony. Robię to w REST API.
Mój kontroler

@PutMapping(value = "/changeEmail", consumes = MediaType.APPLICATION_JSON_VALUE)
    public HttpEntity<ChangeEmailDTO> showChangeEMail(
            @RequestBody @Valid ChangeEmailDTO changeEmailDTO,
            BindingResult result
    ) {
        System.out.println("Email: " + changeEmailDTO.getEmail());
 
        if(result.hasErrors()) {
            System.out.println("Error: " + changeEmailDTO.getEmail());
            return ResponseEntity.badRequest().body(changeEmailDTO);
        }
 
        System.out.println("Success: " + changeEmailDTO.getEmail());
        return ResponseEntity.ok(changeEmailDTO);
    }

przyjmuje adres email, waliduje w adnotacjach

 @NotEmpty
    @Getter @Setter private String email;

Według podanego wyżej poradnika, podobno powinno zwrócić error code w postaci json. Natomiast jedyny efekt jaki otrzymuje to https://zapodaj.net/81a6db4635168.png.html
Czyli zwraca mi sam obiekt, a nie tak jak np. w poradniku

{"timestamp":1417379464584,"status":400,"error":"Bad Request","exception":"org.springframework.web.bind.MethodArgumentNotValidException","message":"Validation failed for argument at index 0 in method: public org.springframework.http.ResponseEntity<demo.AgencyResource> demo.AgencyController.saveAgency(demo.AgencyResource), with 2 error(s): [Field error in object 'agencyResource' on field 'name': rejected value [null]; codes [NotNull.agencyResource.name,NotNull.name,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [agencyResource.name,name]; arguments []; default message [name]]; default message [may not be null]] [Field error in object 'agencyResource' on field 'id': rejected value [50]; codes [Max.agencyResource.id,Max.id,Max.java.lang.Integer,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [agencyResource.id,id]; arguments []; default message [id],20]; default message [must be less than or equal to 20]] ","path":"/agencies"}

W jaki sposób zwrócić takie dane?

komentarz 27 lipca 2017 przez Mateusz51 Nałogowiec (28,180 p.)
Samo throw httpexception nie wystarczy?
komentarz 28 lipca 2017 przez Jonki Dyskutant (8,180 p.)

Nie udało mi się zwrócić takich danych ja w poradniku, ale bardzo podobny.

Zmieniłem kontroler:

@PutMapping(value = "/changeEmail", consumes = MediaType.APPLICATION_JSON_VALUE)
    public HttpEntity<ChangeEmailDTO> showChangeEMail(
            @RequestBody @Valid ChangeEmailDTO changeEmailDTO
    ) {
        System.out.println("Email: " + changeEmailDTO.getEmail());

        return ResponseEntity.ok(changeEmailDTO);
    }

i stworzyłem exception handler dla MethodArgumentNotValidException

@ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ValidationErrorDTO processValidationError(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        List<FieldError> fieldErrors = result.getFieldErrors();

        return processFieldErrors(fieldErrors);
    }

    private ValidationErrorDTO processFieldErrors(List<FieldError> fieldErrors) {
        ValidationErrorDTO dto = new ValidationErrorDTO();

        for (FieldError fieldError: fieldErrors) {
            String localizedErrorMessage = resolveLocalizedErrorMessage(fieldError);
            dto.addFieldError(fieldError.getField(), localizedErrorMessage);
        }

        return dto;
    }

    private String resolveLocalizedErrorMessage(FieldError fieldError) {
        Locale currentLocale =  LocaleContextHolder.getLocale();
        String localizedErrorMessage = messageSource.getMessage(fieldError, currentLocale);

        //If the message was not found, return the most accurate field error code instead.
        //You can remove this check if you prefer to get the default error message.
        if (localizedErrorMessage.equals(fieldError.getDefaultMessage())) {
            String[] fieldErrorCodes = fieldError.getCodes();
            localizedErrorMessage = fieldErrorCodes[0];
        }

        return localizedErrorMessage;
    }

dzięki temu zwraca mi ładną listę błędów https://zapodaj.net/7e359361ed05a.png.html

Tylko jest mały szczególik, że podczas gdy ten wyjątek ma być obsłużony przez ExceptionHandler to wyrzuca mi go również w konsoli

org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument at index 0 in method: public org.springframework.http.HttpEntity<com.movie.database.app.dto.ChangeEmailDTO> com.movie.database.app.rest.controller.UserController.showChangeEMail(com.movie.database.app.dto.ChangeEmailDTO), with 2 error(s): [Field error in object 'changeEmailDTO' on field 'email': rejected value []; codes [IsValidEmail.changeEmailDTO.email,IsValidEmail.email,IsValidEmail.java.lang.String,IsValidEmail]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [changeEmailDTO.email,email]; arguments []; default message [email]]; default message [Please enter a valid e-mail address.]] [Field error in object 'changeEmailDTO' on field 'email': rejected value []; codes [NotEmpty.changeEmailDTO.email,NotEmpty.email,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [changeEmailDTO.email,email]; arguments []; default message [email]]; default message [may not be empty]] 

Jak go obsłużyć, aby nie wyświetlał się w konsoli.

komentarz 31 lipca 2017 przez event15 Szeryf (93,790 p.)
Chciałbym zauważyć, że samo podanie w endpoincie "/changeEmail" deklasyfikuje to API jako REST.

1 odpowiedź

0 głosów
odpowiedź 31 lipca 2017 przez Mar Cin Dyskutant (8,900 p.)
BindingResult result - bezsensu w to iść.

@Adnotacje na encjach

Zrób sobie jakiegoś checkState(T t) - i rzucaj wyjątkiem, prościej, ładniej :)

 

ps żeby ten checkState ładniej wyglądał, niech przyjmuję jakieś wyrażenie lambda.

Podobne pytania

+1 głos
2 odpowiedzi 674 wizyt
pytanie zadane 26 lipca 2017 w Java przez Jonki Dyskutant (8,180 p.)
0 głosów
1 odpowiedź 212 wizyt
pytanie zadane 25 listopada 2019 w JavaScript przez varespol Użytkownik (710 p.)
0 głosów
2 odpowiedzi 668 wizyt
pytanie zadane 24 lutego 2018 w Java przez KubenQPL Maniak (62,820 p.)

92,454 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...