Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return a custom response pojo when request body fails validations that are defined using Bean Validation/Hibernate Validator?

Is it possible to override the default response POJO of Spring Hibernate validator?

Currently when a validation gets failed then a very big response returned to the client as shown below. But I don't want the client to provide the full error response of hibernate validator and instead to send some key-value pair regarding the error message.

{
    "timestamp": "2018-05-28T18:12:56.705+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "NotBlank.abc.xyz",
                "NotBlank.xyz",
                "NotBlank.java.lang.String",
                "NotBlank"
            ],
            "arguments": [
                {
                    "codes": [
                        "abc.xyz",
                        "xyz"
                    ],
                    "arguments": null,
                    "defaultMessage": "transactionId",
                    "code": "transactionId"
                }
            ],
            "defaultMessage": "xyz is mandatory parameter , please provide appropriate value",
            "objectName": "abc",
            "field": "xyz",
            "rejectedValue": "",
            "bindingFailure": false,
            "code": "NotBlank"
        }
    ],
    "message": "Validation failed for object='xyz'. Error count: 1",
    "path": "/path/create/1"
}
like image 286
Vivek Garg Avatar asked May 28 '18 18:05

Vivek Garg


People also ask

Which object is used by a request processing method to check validation failure?

The Validator interface works using an Errors object so that while validating, validators can report validation failures to the Errors object.

How do I customize default error message from Spring @valid validation?

You can perform validation with Errors/BindingResult object. Add Errors argument to your controller method and customize the error message when errors found. Below is the sample example, errors. hasErrors() returns true when validation is failed.

Where is @valid annotation is used to validate a form?

In controller class: The @Valid annotation applies validation rules on the provided object. The BindingResult interface contains the result of validation.


1 Answers

A BindException is thrown when the request body fails validation. You can define your own ControllerAdvice that construct an appropriate error message from the details in the BindException.

import java.util.ArrayList;
import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.example.demo.ErrorResponse.ErrorDetails;

@ControllerAdvice
public class CustomExceptionHandler {

    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public ErrorResponse handleException(BindException ex) {

        List<FieldError> errors = ex.getBindingResult().getFieldErrors();

        List<ErrorDetails> errorDetails = new ArrayList<>();
        for (FieldError fieldError : errors) {
            ErrorDetails error = new ErrorDetails();
            error.setFieldName(fieldError.getField());
            error.setMessage(fieldError.getDefaultMessage());
            errorDetails.add(error);
        }

        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setErrors(errorDetails);

        return errorResponse;
    }

}

Pojo for the error response:

@Data
public class ErrorResponse {

    private List<ErrorDetails> errors;

    @Data
    public static class ErrorDetails {
        private String fieldName;
        private String message;
    }
}

Sample error message

{
    "errors": [
        {
            "fieldName": "firstName",
            "message": "must not be null"
        },
        {
            "fieldName": "lastName",
            "message": "must not be null"
        }
    ]
}
like image 85
Ranjith Avatar answered Sep 28 '22 05:09

Ranjith