当请求正文未通过使用 Bean Validation/Hibernate Validator 定义的验证时,如何 return 自定义响应 pojo?
How to return a custom response pojo when request body fails validations that are defined using Bean Validation/Hibernate Validator?
是否可以覆盖 Spring Hibernate 验证器的默认响应 POJO?
目前,当验证失败时,会向客户端返回一个非常大的响应,如下所示。但是我不希望客户端提供休眠验证器的完整错误响应,而是发送一些关于错误消息的键值对。
{
"timestamp": "2018-05-28T18:12:56.705+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"NotBlank.abc.xyz",
"NotBlank.xyz",
"NotBlank.java.lang.String",
"NotBlank"
],
"arguments": [
{
"codes": [
"abc.xyz",
"xyz"
],
"arguments": null,
"defaultMessage": "transactionId",
"code": "transactionId"
}
],
"defaultMessage": "xyz is mandatory parameter , please provide appropriate value",
"objectName": "abc",
"field": "xyz",
"rejectedValue": "",
"bindingFailure": false,
"code": "NotBlank"
}
],
"message": "Validation failed for object='xyz'. Error count: 1",
"path": "/path/create/1"
}
当请求正文验证失败时抛出 BindException
。您可以定义自己的 ControllerAdvice
,根据 BindException
.
中的详细信息构建适当的错误消息
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.example.demo.ErrorResponse.ErrorDetails;
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handleException(BindException ex) {
List<FieldError> errors = ex.getBindingResult().getFieldErrors();
List<ErrorDetails> errorDetails = new ArrayList<>();
for (FieldError fieldError : errors) {
ErrorDetails error = new ErrorDetails();
error.setFieldName(fieldError.getField());
error.setMessage(fieldError.getDefaultMessage());
errorDetails.add(error);
}
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setErrors(errorDetails);
return errorResponse;
}
}
错误响应的 Pojo:
@Data
public class ErrorResponse {
private List<ErrorDetails> errors;
@Data
public static class ErrorDetails {
private String fieldName;
private String message;
}
}
示例错误消息
{
"errors": [
{
"fieldName": "firstName",
"message": "must not be null"
},
{
"fieldName": "lastName",
"message": "must not be null"
}
]
}
是否可以覆盖 Spring Hibernate 验证器的默认响应 POJO?
目前,当验证失败时,会向客户端返回一个非常大的响应,如下所示。但是我不希望客户端提供休眠验证器的完整错误响应,而是发送一些关于错误消息的键值对。
{
"timestamp": "2018-05-28T18:12:56.705+0000",
"status": 400,
"error": "Bad Request",
"errors": [
{
"codes": [
"NotBlank.abc.xyz",
"NotBlank.xyz",
"NotBlank.java.lang.String",
"NotBlank"
],
"arguments": [
{
"codes": [
"abc.xyz",
"xyz"
],
"arguments": null,
"defaultMessage": "transactionId",
"code": "transactionId"
}
],
"defaultMessage": "xyz is mandatory parameter , please provide appropriate value",
"objectName": "abc",
"field": "xyz",
"rejectedValue": "",
"bindingFailure": false,
"code": "NotBlank"
}
],
"message": "Validation failed for object='xyz'. Error count: 1",
"path": "/path/create/1"
}
当请求正文验证失败时抛出 BindException
。您可以定义自己的 ControllerAdvice
,根据 BindException
.
import java.util.ArrayList;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.example.demo.ErrorResponse.ErrorDetails;
@ControllerAdvice
public class CustomExceptionHandler {
@ExceptionHandler(BindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public ErrorResponse handleException(BindException ex) {
List<FieldError> errors = ex.getBindingResult().getFieldErrors();
List<ErrorDetails> errorDetails = new ArrayList<>();
for (FieldError fieldError : errors) {
ErrorDetails error = new ErrorDetails();
error.setFieldName(fieldError.getField());
error.setMessage(fieldError.getDefaultMessage());
errorDetails.add(error);
}
ErrorResponse errorResponse = new ErrorResponse();
errorResponse.setErrors(errorDetails);
return errorResponse;
}
}
错误响应的 Pojo:
@Data
public class ErrorResponse {
private List<ErrorDetails> errors;
@Data
public static class ErrorDetails {
private String fieldName;
private String message;
}
}
示例错误消息
{
"errors": [
{
"fieldName": "firstName",
"message": "must not be null"
},
{
"fieldName": "lastName",
"message": "must not be null"
}
]
}