DEV Community

Cover image for How to Align Spring Boot Validation Errors with Your JSON Property Naming Strategy
İbrahim Gündüz
İbrahim Gündüz

Posted on • Originally published at Medium

How to Align Spring Boot Validation Errors with Your JSON Property Naming Strategy

Problem

Our API uses a snake_case naming strategy for DTO deserialization and serialization. However, when validation fails, the error messages still use the original object property names, ignoring the configured naming strategy, which leads to inconsistent API responses.

Solution

This issue occurs because bean validation happens after the incoming request has been deserialized into the DTO, but before the response is serialized. As a result, validation errors report the Java field names rather than the JSON property names defined by the configured naming strategy.

First, make sure that the property naming strategy is configured as shown below:

# application.properties

spring.jackson.property-naming-strategy=SNAKE_CASE
Enter fullscreen mode Exit fullscreen mode

Override the default error generation with creating a custom error handler.

@RestControllerAdvice
public class ValidationExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {
       // TODO: To be implemented
    }
}
Enter fullscreen mode Exit fullscreen mode

To access the mapped field names, inject an ObjectMapper and resolve the JSON property names by iterating over the list of field errors.

private final ObjectMapper objectMapper;

//...

@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException exception) {
  List<String> errors = exception.getBindingResult()
          .getFieldErrors()
          .stream()
          .map(this::formatErrorMessage)
          .toList();

  return ResponseEntity.badRequest().body(Map.of("errors", errors));
}

private String formatErrorMessage(FieldError fieldError) {
  PropertyNamingStrategy mapping = objectMapper.getPropertyNamingStrategy();
  String mappedFieldName = mapping.nameForField(null, null, fieldError.getField());

  return String.format("%s.%s: %s", fieldError.getObjectName(), mappedFieldName, fieldError.getDefaultMessage());
}
Enter fullscreen mode Exit fullscreen mode

Let’s test it!

$ curl -XPOST "http://api.yourdomain.com/v1/merchants" \
-H "Content-Type: application/json" \
-d "{}"

{
  "errors" : [ 
    "merchantCreateRequest.partner_id: must not be null", 
    "merchantCreateRequest.merchant_name: must not be null" 
  ]
}%                                                    
Enter fullscreen mode Exit fullscreen mode

You can find all code examples in the following repository:
https://github.com/ibrahimgunduz34/blog-code-examples/tree/master/spring-boot-validation-error

Thanks for reading!

Top comments (0)