spring - 当请求正文未通过使用 Bean Validation/Hibernate Validator 定义的验证时,如何返回自定义响应 pojo?

标签 spring spring-boot bean-validation hibernate-validator

是否可以覆盖 Spring Hibernate 验证器的默认响应 POJO?

当前,当验证失败时,会向客户端返回一个非常大的响应,如下所示。但我不希望客户端提供 hibernate 验证器的完整错误响应,而是发送一些有关错误消息的键值对。

{
    "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 - 当请求正文未通过使用 Bean Validation/Hibernate Validator 定义的验证时,如何返回自定义响应 pojo?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50571687/

相关文章:

java - 如何使用JAVA代码获取Spring框架中数据源的值?

java - 如何从rest webservice spring返回自定义响应

java - @Validated 未考虑

java - Spring不创建ConstraintValidator

java - SpringValidator(net.sf.oval): Recursive Error Reporting

java - Spring Boot - Junit 无法在 junit 测试中加载配置属性

java - Jersey Web 服务中 Spring DI 中的 NPE

java - Spring cloud AWS:发送到SQS URL,而不是队列名称

spring-boot - Neo4j 无法将 java.lang.Long 字段 model.Authority.id 设置为 model.Authority

spring-boot - 在类路径中具有 "spring-boot-starter-test"依赖项时无法启动 tomcat 服务器