I am new to Spring boot and I have a question about request fields validation. I figured out how to use annotations on fields level to specify the custom error message:
public class EmployeeRequest {
@NotEmpty( message = "field name cannot be empty" )
@NonNull
private String name;
@NotEmpty( message = "field address cannot be empty" )
@NonNull
private String address;
}
But for using these annotations I have to specify error message for every field in every request class. Also for some reason I am getting not very neat response:
"org.springframework.validation.BeanPropertyBindingResult: 1 errors\\nField error in object 'employeeRequest' on field 'name': rejected value [null]; codes [NotEmpty.employeeRequest.name,NotEmpty.name,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [employeeRequest.name,name]; arguments []; default message [name]]; default message [provide a name]"
Is there more elegant and generic way to do such field validations for every request assuming all fields must be NotEmpty
and NonNull
?
public class EmployeeController {
@PostMapping("/test")
@ResponseBody
public EmployeeResponse testMethod(@RequestBody EmployeeRequest request) {
genericFieldsValidatorForAllRequests(request);
doSomeStuffIfRequestIsValid(request);
}
Could anybody provide some ideas how that request validator could be implemented?
It seems like you asked two questions, hopefully I can try to answer both.
By default Spring Boot catches any uncaught exception thrown in a web request handler (such as @RequestMapping
, @GetMapping
, etc...) and converts it into a JSON response of this structure below:
{
"timestamp": 1500597044204,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "JSON parse error: Unrecognized token .....",
"path": "/birds"
}
One way to get your error response JSON to look a different way is to make an exception handler. Basically you catch the errors you want before they go to Spring Boot's default error handler. To do that you make one of these somewhere in the same package or a higher lever package than your controller:
@ControllerAdvice
public class GlobalErrorHandler {
@ExceptionHandler(ExceptionICareAbout.class)
public MyErrorResponseObject handleExceptionICareAbout(ExceptionICareAbout e) {
return new MyErrorResponseObject(<ADD CODE HERE>)
}
}
In your case, you could make an exception handler for MethodArgumentNotValidException
and convert it into the error response of your liking. (I believe that is the exception that is thrown when a JSR303 annotation validation fails, but please double check me)
You can also wrap your error response object in a ResponseEntity<>
object that Spring provides to customize other things in the response, or just annotate the exception handler method with @ResponseStatus
to customize just the http status code that is returned.
Also, if you want to catch every single exception and prevent them from going to Spring Boot's default exception handler, just make a exception handler for the Exception
class itself, such as @ExceptionHandler(Exception.class)
.
Using the JSR303 annotations like you are ( @NotNull
, @Size
, etc...) per field on every object you care about in combination with the @Valid
annotation is the best way I know. I would spend time thinking about ways to reuse code and error messages, but that's all I can think of off the top of my head. Maybe we can get some good answers in the comments.
Spring does offer these Validators you could do instead of JSR303 annotation, but I don't have much experience with them.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.