Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not getting proper response while bean validation failed in spring boot app

I am using spring boot 2.0.6, hibernate validator 6.0, validation-api 2.0, and apache cxf. I used @Valid annotation in controler method and then i set @NotNull, @Email with proper messages in bean properties. Then I created a CustomExceptionHandler to handle the MethodArgumentNotValidException. while testing it by postman i am not getting the proper response with my validation message.

UserController.class

@Path("/user")
@Component
public class UserController {

@POST
@Path("/register")
@Consumes(MediaType.APPLICATION_JSON_VALUE)
@Produces(MediaType.APPLICATION_JSON_VALUE)
public Response registerUser(@Valid User user) {

    String status = "";

    Boolean isEmailIdExist = UserAuthService.checkUserByMailId(user.getEmail());
    Boolean isUserNameExist = UserAuthService.checkUserByUserName(user.getUserName());

    if(!isEmailIdExist) {
        if(!isUserNameExist) {
            status = UserAuthService.registerUser(user);
        }else {
            status = "Username already taken. Try with different name";
        }
    }else {
        status = "Email ID already exist";
    }

    return Response.ok(status).build();
}
}

User.class

@Entity
@Table(name = "USER")
public class User {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "UID")
private int userId;

@NotBlank(message = "Please provide first name")
@Column(name = "FIRST_NAME", length = 50)
private String firstName;

@NotBlank(message = "Please provide email")
@Column(name = "EMAIL", length = 100, unique = true)
@Email(message = "Please provide a valid email")
private String email;}

getter/setter
}

CustomExceptionHandler.java

@ControllerAdvice
@Component
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

@ExceptionHandler(Exception.class)
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
    ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
    return new ResponseEntity<Object>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
}

@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
        HttpHeaders headers, HttpStatus status, WebRequest request) {
    ErrorDetails errorDetails = new ErrorDetails(new Date(), "Validation Failed", ex.getBindingResult().toString());
    return new ResponseEntity<Object>(errorDetails, HttpStatus.BAD_REQUEST);
}
}

Json Structure

{
    "firstName":"",
    "email":"[email protected]",
}
like image 324
Prakash kumar mallick Avatar asked Nov 22 '18 09:11

Prakash kumar mallick


1 Answers

If your experiencing the issue of for example: not being able to see the validation errors (default-messages) returned back to the client, this is what you could do:

Top Solution 1: Simply add devtools. This should solve the issue. After I did this, all my binding-results were returned back to the client. I recommend you to test this out first:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
</dependency>

Solution 2:

I found out that this is due to using Spring Boot 2.3+ So if youre using Spring Boot 2.3 or higher, add this dependency in your pom.xml file as its no longer included within the 'web'-dependency itself.

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Now its necessary to set 'include binding errors' in java/resources/application.properties to "always". Same goes for 'message' as well although I think this is optional.

server.error.include-message=always
server.error.include-binding-errors=always

Solution 3: (before I discovered solution 2 which could be helpful as well)

So I found out that this is due to having Spring boot 2.3+. But I could not find caution-messages on the new updated usage of @Valid in Spring Boot v2.3+.

So I ended up switching back to Spring boot v2.2.10 (latest version of 2.2) by adjusting the release version in the pom.xml file like so:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.10.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

This worked perfectly for me by rolling back to an older version. Although id like to update my Spring Boot version some day. (Revisit solution 1 & 2)

like image 155
Esther Avatar answered Sep 28 '22 14:09

Esther