【问题标题】:Different response models in spring春季不同的响应模型
【发布时间】:2021-07-29 05:21:23
【问题描述】:

我正在使用 maven codgen 插件为我生成代码。但是,如果捕获到 API 异常,我想返回一个不同的模型。但它似乎不起作用。

我想返回 e.getResponseBody();无论外部 api 返回什么。 但是错误模型和List不一样。

例如。使用简单的宠物示例(并将“默认”响应更改为“400”):

      responses:
        '200':
          description: pet response
          schema:
            type: array
            items:
              $ref: '#/definitions/pet'
        '400':
          description: unexpected error
          schema:
            $ref: '#/definitions/errorModel'

生成如下界面:

@ApiOperation(value = "", notes = "Returns all pets from the system that the user has access to", response = Pet.class, responseContainer = "List", tags={  })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "pet response", response = Pet.class),
        @ApiResponse(code = 400, message = "unexpected error", response = errorModel.class) })
    @RequestMapping(value = "/pets",
        produces = { "application/json", "application/xml", "text/xml", "text/html" }, 
        consumes = { "application/json" },
        method = RequestMethod.GET)
    ResponseEntity<List<Pet>> findPets(@ApiParam(value = "tags to filter by") @RequestParam(value = "tags", required = false) List<String> tags,
        @ApiParam(value = "maximum number of results to return") @RequestParam(value = "limit", required = false) Integer limit);

控制器

 ResponseEntity<List<Pet>> findPets(@ApiParam(value = "tags to filter by") @RequestParam(value = "tags", required = false) List<String> tags,
        @ApiParam(value = "maximum number of results to return") @RequestParam(value = "limit", required = false) Integer limit){
   try{
     //call external api which throw a API exception if fail
   }
   catch(ApiException e){
   // I would like to return e.getResponseBody(); whatever it is returned by external api. 
  // But the error model is not the same as List<Pet>
}

}

【问题讨论】:

    标签: java spring error-handling swagger-codegen


    【解决方案1】:

    Spring 为您提供了一种比直接在控制器中捕获 ApiException 更好的方法。您应该记录自己在 REST apis 中的异常处理(考虑阅读https://www.baeldung.com/exception-handling-for-rest-with-spring

    根据您的 spring 版本,您可以使用 @ControllerAdvice 注释,我认为这是最简单的方法。

    从您的控制器中删除 try/catch :

    ResponseEntity<List<Pet>> findPets(@ApiParam(value = "tags to filter by") @RequestParam(value = "tags", required = false) List<String> tags,
            @ApiParam(value = "maximum number of results to return") @RequestParam(value = "limit", required = false) Integer limit) 
    throws ApiException
    {
       
       //call external api which throw a API exception if fail
       
    }
    

    创建一个带有@ControllerAdvice注解的类

    @ControllerAdvice
    public class APIExceptionHandler 
      extends ResponseEntityExceptionHandler {
    
        @ExceptionHandler(value 
          = ApiException.class)
        protected ResponseEntity<MyExceptionResponseDto> handleException(
          ApiException ex, WebRequest request) {
            MyExceptionResponseDto apiError = ... //TODO
            return new ResponseEntity<>(apiError, HttpStatus.INTERNAL_SERVER_ERROR)
        }
    }
    

    注意:MyExceptionResponseDto 是代表您的错误响应的 DTO

    这还允许您选择一个特定的 HTTP 错误代码,该代码在客户端处理错误时很重要(不仅仅是基于 json 中的属性)

    【讨论】:

    • 问题在于,使用 maven codegen,我的控制器必须遵循接口中的定义
    猜你喜欢
    • 2015-08-31
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 2013-07-21
    • 2011-09-22
    • 1970-01-01
    相关资源
    最近更新 更多