user8353997
user8353997

Reputation:

Return code error as ResponseEntity after DTO validation in REST API

Using the https://www.leveluplunch.com/java/tutorials/017-validate-spring-rest-webservice-request/ tutorial, I want to validate the form using java without reloading the page. I do this in the REST API. My controller

@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);
}

Accepts email address, validates in annotations

    @NotEmpty
   @Getter @Setter private String email;

According to the above guide, it is supposed to return an error code in json form. The only effect it receives is https://zapodaj.net/81a6db4635168.png.html. So it returns the object itself, not like in the tutorial

{"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"}

How to return such data?

Upvotes: 3

Views: 4012

Answers (2)

Bohdan Levchenko
Bohdan Levchenko

Reputation: 3561

Remove the BindingResult result parameter from the showChangeEMail method signature and the corresponding if and you'll get an exception back just like in the tutorial you've mentioned above.

Nevertheless it might look like a bug or a magic it is not. Spring-mvc is able to check this argument presence and if so do not throw any exception assuming that you're handling validation errors by yourself. Otherwise - an exception will be thrown.

For information check the source of RequestResponseBodyMethodProcessor which is responsible for this behavior.

Upvotes: 1

Sangam Belose
Sangam Belose

Reputation: 4506

You are taking control over the response in case of ValidationException using BindingResult.hasErrors(). And in this case you return your DTO with Bad Request http status code as below.

return ResponseEntity.badRequest().body(changeEmailDTO);

The mentioned tutorial has default Exception handler provide by spring which transforms the Exception into that message.

Just remove the BindingResult from method signature and then any kind of validation exception will be caught by default Exceptionhandler. Then you will get the mentioned response.

Upvotes: 1

Related Questions