1

Hello I'm a beginner in Java and I have problem with javax validation using SpringBoot. I created my own ExceptionHandler to handle validation exception: MethodArgumentNotValidException which is thrown when request is invalid.

Invalid JSON request example:

{
    "code": "",
    "name": ""
}

Controller:

@Controller
@RequestMapping("/v1/api")
public class ApiController {

    @Autowired
    private Service service;

    @PostMapping("/")
    public ResponseEntity<?> returnHomePage(@Valid @RequestBody RequestDTO requestDTO) {
        return ResponseEntity.ok().body(service.getSomeData(requestDTO));
}

}

Class with javax validation annotations:

@Data
public class RequestDTO {
    @NotBlank(message = "Return code is a required field")
    @Size(min = 6, max = 10, message = "Return code must be in range 6-10 digits")
    @Pattern(regexp = "[\\d]{6,10}", message = "Return code must be numeric")
    private String code;
    @NotBlank(message = "Name is a required field")
    @Size(min = 1, max = 15, message = "Name must be in range 1-15 digits")
    private String name;

}

Method in my Handler:

@ExceptionHandler(value = {MethodArgumentNotValidException.class})
public ResponseEntity<Object> handleBadRequestException(MethodArgumentNotValidException ex, WebRequest request) {
    List<String> errorMessages = new ArrayList<>();

    Map<String, List<String>> details = ex
        .getBindingResult()
        .getFieldErrors()
        .stream()
        .collect(Collectors.toMap(FieldError::getField, fieldError -> {
            errorMessages.add(fieldError.getDefaultMessage());
            return errorMessages;
        }, (key, duplicatedKey) -> key));

    ErrorMessage errorMessage = new ErrorMessage(HttpStatus.BAD_REQUEST.name().toLowerCase(), ex.getMessage(), details);
    return new ResponseEntity<>(errorMessage, HttpStatus.BAD_REQUEST);

ErrorMessage class:

@Data
@AllArgsConstructor
public class ErrorMessage {
    private final String key;
    private final String msg;
    private final Map<String, List<String>> details;
}

What I want to achieve is to get nested validation errors per field like in example below:

{
    "key": "bad_request",
    "msg": "Validation errors occurred",
    "details": {
        "code": [
            "Return code must be numeric",
            "Return code must be in range 6-10 digits",
            "Return code is a required field",
        ],
        "name": [
            "Name must be in range 1-15 digits",
            "Name is a required field",
        ]
    }
}

What I am getting at this point:

{
    "key": "bad_request",
    "msg": "Validation errors occurred",
    "details": {
        "code": [
            "Return code is a required field",
            "Name is a required field",
            "Return code must be in range 6-10 digits",
            "Name must be in range 1-15 digits",
            "Return code must be numeric"
        ],
        "name": [
            "Return code is a required field",
            "Name is a required field",
            "Return code must be in range 6-10 digits",
            "Name must be in range 1-15 digits",
            "Return code must be numeric"
        ]
    }
}

As you can see both code and name keys get validation errors for both fields which ofc is wrong :) I'll be grateful for any help :)

0 Answers0