I'm writing REST-API using Spring MVC framework.
I'm using bean-validation like:
class Person {
@NotNull
String name;
@NotNull
String email;
@Min(0)
Integer age;
}
I'm validating Person using @Valid annotation into controllers:
@PostMapping
public Person create(@Valid @RequestBody Person person) {return ...;}
To make errors human-readable I use spring's top level error handler:
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody String handle(MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult().getFieldErrors().stream()
.map(this::buildMessage)
.collect(Collectors.toList());
return errors.toString();
}
private String buildMessage(FieldError fe) {
return fe.getField() + " " + fe.getDefaultMessage();
}
}
So my errors looks like: [name may not be null, email may not be null]
Now I need to use language independent error code that will be parsed by different UIs to implement i18n.
Is there any way to build full error code? (that contains field name)
I see the following solutions:
Use custom message every time I used annotation (ugly):
class Person { @NotNull(message="app.error.person.name.not.null") String name; @NotNull(message="app.error.person.email.not.null") String email; @Min(0)(message="app.error.person.age.below.zero") Integer age; }Build correct code into my exception handler(don't know how):
private String buildMessage(FieldError fe) { return "app.error." + fe.getObjectName() + "." + fe.getField() + "." + fe.getDefaultMessage().replaceAll("\\s", "");//don't know how to connect to concrete annotation }so message will be like
app.error.person.name.maynotbenullRe-write all annotations and validators for them to build correct message by removing default ConstraintViolation and adding custom (overhead)