Jefferson Lima
Jefferson Lima

Reputation: 5396

Response error format with manual validation in Spring Data Rest

When using Spring Data REST and JSR 303 Bean Validation I get a response like the following when there's a constraint violation:

{
    "errors": [
        {
            "entity": "Empresa",
            "property": "observacao",
            "invalidValue": "",
            "message": "O tamanho do campo deve ser entre 1 e 255"
        }
    ]
}

But I'm trying to validate an object manually, and I would like to return the validation errors in the same format used by Spring Data Rest.

  @DeleteMapping("/departamento/{id}")
  public @ResponseBody
  ResponseEntity<?> filtro(@PathVariable Long id){

    Optional<Departamento> departamentoOpt = this.departamentoRepository.findById(id);

    if (!departamentoOpt.isPresent()) {
      return ResponseEntity.notFound().build();
    }

    Departamento departamento = departamentoOpt.get();

    BindingResult errors = new BeanPropertyBindingResult(
        departamento, "departamento");

    this.validator.validate(departamento, errors, PreDeleteValidation.class);

    if (errors.hasErrors()) {
      // How to return a response in the same format used by SDR here?
    }

    return ResponseEntity.ok().build();

  }

How can this be accomplished?

Upvotes: 0

Views: 452

Answers (1)

Alan Hay
Alan Hay

Reputation: 23226

You can throw and Exception on validation failure and register a Spring MVC Controller Advice to catch this and transform it to something that meets your needs.

if (errors.hasErrors()) {
  throw new org.springframework.web.bind.MethodArgumentNotValidException(
                 departamento, bindingResult)
}

The advice could look something like the below:

@ControllerAdvice
public class ErrorHandlingAdvice
{
  @ExceptionHandler(MethodArgumentNotValidException.class)
  @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ResponseBody
  public ValidationError processValidationError(MethodArgumentNotValidException ex)
  {
    ValidationError error = new ValidationError();
    BindingResult result = ex.getBindingResult();
    List<FieldError> fieldErrors = result.getFieldErrors();

    for (FieldError fieldError : fieldErrors)
    {
      error.addError(fieldError.getField(), fieldError.getDefaultMessage());
    }

    return error;
  }
}

ValidationError is just a simple bean:

public class ValidationError
{
  private final Map<String, List<String>> errors;

  public ValidationError()
  {
    errors = new TreeMap<>();
  }

  public void addError(String field, String error)
  {
    if (!errors.containsKey(field))
    {
      errors.put(field, new ArrayList<String>());
    }

    errors.get(field).add(error);
  }

  public Map<String, List<String>> getErrors()
  {
    return errors;
  }
}

Upvotes: 1

Related Questions