java - Spring Boot API 自定义错误响应契约

标签 java spring rest api spring-boot

我正在尝试使用 Java Spring 引导构建一个 TODO 应用程序。在 Controller 层添加了验证,以确保创建 API 的待办事项名称长度在 2 到 10 之间。我已配置为成功返回以下响应:

{
  "success": true,
  "data": {"name": "hello", "completed": false},
  "errors": []
}

我也想在失败的情况下返回相同的契约(Contract)。但是当我尝试发出失败的请求(名称大于 10 个字符)时,服务器以某种方式返回以下响应。

{
"timestamp": "2019-11-21T15:41:28.545+0000",
"status": 400,
"error": "Bad Request",
"errors": [
    {
        "codes": [
            "Size.createTodoContract.name",
            "Size.name",
            "Size.java.lang.String",
            "Size"
        ],
        "arguments": [
            {
                "codes": [
                    "createTodoContract.name",
                    "name"
                ],
                "arguments": null,
                "defaultMessage": "name",
                "code": "name"
            },
            10,
            2
        ],
        "defaultMessage": "size must be between 2 and 10",
        "objectName": "createTodoContract",
        "field": "name",
        "rejectedValue": "attend wedding",
        "bindingFailure": false,
        "code": "Size"
    }
],
"message": "Validation failed for object='createTodoContract'. Error count: 1",
"path": "/api/todos"
}

我的负载验证如下:

@Getter
public class CreateTodoContract {
  @Size(min = 2, max = 10)
  private String name;

  @NotNull
  private boolean completed;
}

请帮助我了解我应该在哪里更新失败案例的实际契约(Contract)?

最佳答案

您在项目中弄乱了一些编码部分。

1) 首先,为所有@Size 注释和所有其他与验证相关的注释(@NotNull、@NotEmpty 等)添加“消息”属性。当您尝试发出失败请求时,API 将返回您在“消息”属性中提到的错误消息。请参阅下面的代码行。对这些注释使用 javax.validation.constraints 库。其他也还行。但这要好得多。

@Size(min = 1, message = "email can not be empty")
@NotNull(message = "email can not be null")
private String email;

2) 然后,您应该使用“BindingResult”类 (org.springframework.validation) 在 Controller (API 定义)中捕获这些无效场景,如下所示。以及你应该为你的请求正文使用@Valid annotaion(CreateTodoContract)否则服务器正在重新调整你在问题中提到的无效场景的响应。

@PostMapping(value = "createTodoContract")
public ResponseEntity<Object> CreateTodoContract(@Valid @RequestBody 
                                                 CreateTodoContract 
                                                 createTodoContractRequest,
                                                 BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        String error = bindingResult.getAllErrors().get(0).getDefaultMessage();
        return new ResponseEntity<>(responseBuilder.build("02", error), status);
    }

    return new ResponseEntity<>(response, response.getStatus());

}

字符串错误 = bindingResult.getAllErrors().get(0).getDefaultMessage()

您可以使用上面的代码行获取错误消息。

如果您的 API 请求有多个请求参数需要验证,请使用下面提到的代码行来捕获错误消息。否则,API 会不时收到您在代码库中提到的不同错误消息(偶发问题)

if (bindingResult.hasErrors()) {
        String error = bindingResult.getAllErrors().get(0).getDefaultMessage();

        if (bindingResult.getAllErrors().size() == 1) {
            return new ResponseEntity<>(responseBuilder.build("02", error), status);

        } else {
            return new ResponseEntity<>(
                    responseBuilder.build("02", "mandatory parameters can not be 
            empty, null or invalid"), status);

        }
    }

关于java - Spring Boot API 自定义错误响应契约,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58979188/

相关文章:

java - jackson JSON : Serialize certain properties under different view?

分布式应用程序中的 Spring Security

java - Spring Boot 安全性 - 两个不同的过滤器

jquery - 不允许通过 REST api 和 jquery 405 方法创建 Jira 问题

java - 如何使用 JAVA 将给定的分层 XML 文件转换为非规范化关系数据库表

java - 首选项管理器始终加载默认值

java - 使用 Spring 在 Java 中发送文本 REST 消息

Java Jersey Framework RESTful Web 服务最佳实践

java - Android Studio 请求位置权限弹窗

java - Spring AOP,切入点根据路径变量名触发