I have the following Rest Controller in Java/Spring. The validation of constraints are checked. However, these are completed before it reaches the body of my 'bar' method. How can I handle a violation case? Can I customize the 400 response bodies?
@RestController
@RequestMapping("foo")
public class FooController {
@RequestMapping(value = "bar", method = RequestMethod.POST)
public ResponseEntity<Void> bar(@RequestBody @Valid Foo foo) {
//body part
return ResponseEntity.status(HttpStatus.OK).build();
}
}
You should use controllerAdvice, here is an exemple (in kotlin) :
@ControllerAdvice
open class ExceptionAdvice {
@ExceptionHandler(MethodArgumentNotValidException::class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
open fun methodArgumentNotValidExceptionHandler(request: HttpServletRequest, e: MethodArgumentNotValidException): ErrorDto {
val errors = HashMap<String, String>()
for (violation in e.bindingResult.allErrors) {
if (violation is FieldError) {
errors.put(violation.field, violation.defaultMessage)
}
}
return ErrorDto(errors)
}
@ExceptionHandler(BindException::class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
open fun bindExceptionHandler(request: HttpServletRequest, e: BindException): ErrorDto {
val errors = HashMap<String, String>()
for (violation in e.bindingResult.allErrors) {
if (violation is FieldError) {
errors.put(violation.field, violation.defaultMessage)
}
}
return ErrorDto(errors)
}
}
It allows to handle exception thrown by your controllers, including validation exceptions.
You can add BindingResult as parameter at the end into method signature.
@RequestMapping(value = "bar", method = RequestMethod.POST)
public ResponseEntity<Void> bar(@RequestBody @Valid Foo foo, BindingResult bindingResult)
{
if (bindingResult.hasErrors()) {
//do something if errors occured
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
//body part
return ResponseEntity.status(HttpStatus.OK).build();
}
Annotate Foo
object properly with hibernate annotations and it will work automatically. For example, few validations may be
@NotEmpty(message = "first name must not be empty")
private String firstName;
@NotEmpty(message = "last name must not be empty")
private String lastName;
@NotEmpty(message = "email must not be empty")
@Email(message = "email should be a valid email")
private String email;
To handle other errors, write @ControllerAdvice
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler
{
@ExceptionHandler(RecordNotFoundException.class)
public final ResponseEntity<Object> handleUserNotFoundException(RecordNotFoundException ex, WebRequest request) {
List<String> details = new ArrayList<>();
details.add(ex.getLocalizedMessage());
ErrorResponse error = new ErrorResponse("Record Not Found", details);
return new ResponseEntity(error, HttpStatus.NOT_FOUND);
}
}
And add @Valid annotation like this while accepting request body.
@PostMapping(value = "/employees")
public ResponseEntity<EmployeeVO> addEmployee (@Valid @RequestBody EmployeeVO employee)
{
EmployeeDB.addEmployee(employee);
return new ResponseEntity<EmployeeVO>(employee, HttpStatus.OK);
}
Read more this blog about rest validation in detail.
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.