【问题标题】:Java and OpenAPI - return different payload depend on the response codeJava 和 OpenAPI - 根据响应代码返回不同的有效负载
【发布时间】:2020-03-27 03:49:18
【问题描述】:

开始之前:我查看了以下链接,但没有一个与我的问题相符:

所以,我有一个端点的 OpenAPI 3 定义,它为成功调用返回给定的有效负载(例如200 OK)。但是,对于不成功的调用(例如408 CONFLICT),我想返回一个完全不同的错误负载。

你可以看到下面的定义:

openapi: 3.0.1

info:
  title: Dogs
  description: API to add dogs into a database
  version: 0.0.1

paths:
  /dog:
    post:
      description: Saves a dog into the database

      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Dog"

      responses:
        201:
          description: A dog was added to the system
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Dog"

        400:
          description: This dog already exist in the system
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

components:
  schemas:
    Dog:
      type: object
      properties:
        name:
          type: string
          description: Name of the dog
          example: "barky"

    Error:
      type: object
      properties:
        code:
          type: string
          description: Machine-readable code of the error.
          example: "Already Exists"

        message:
          type: string
          description: A Human-readable error message.
          example: "Empty string is not a valid name for a dog"

由此,我生成了一个Spring 代码(当前使用Swagger editor)。与定义关联的方法签名如下所示:

ResponseEntity<Dog> dogPost(@ApiParam(value = ""  )  @Valid @RequestBody Dog body);

因此 - 我无法在此函数中返回 Error 对象,除非引发异常并稍后捕获 - 我认为这是一种不好的做法,因为无效输入的操作不是异常。

有没有办法很好地解决这个问题而不会抛出异常并将其捕获到函数范围之外?

【问题讨论】:

标签: java spring-boot swagger openapi


【解决方案1】:

有很多方法可以用 Spring Boot 来实现这种需求。其中之一是使用@ExceptionHandler(有关更多信息,请参阅https://www.baeldung.com/exception-handling-for-rest-with-spring),但这确实是在控制器本身之外处理的。该系统的优点是您可以在一个地方实现任何异常到错误对象的转换,而不是分别实现每个控制器方法。

也就是说,如果您确实想在控制器本身中处理它,您可以这样做:

@PostRequest("/dog")
public ResponseEntity<?> createDog(@Valid @RequestBody Dog dog) {
    if( !service.doesDogAlreadyExist(dog) ) {
      Dog dog = service.createDog(dog);
      return ResponseEntity.ok(dog).build();
    } else {
      return ResponseEntity.status(HttpStatus.CONFLICT)
                           .body(/* error object here */)
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-10-02
  • 2020-03-04
  • 1970-01-01
  • 1970-01-01
  • 2015-01-06
  • 2021-11-07
  • 1970-01-01
  • 2017-11-30
相关资源
最近更新 更多