首页 > 解决方案 > 如何隐藏端点的@ApiResponse 表单@ControllerAdvice?

问题描述

我正在尝试将我们手动编写的 OpenAPI (swagger) 迁移到使用 springdoc-openapi 为我们的 Spring-Boot 应用程序生成的 OpenAPI。我们遇到了一些问题,因为控制器响应(主要是错误代码)与文档不匹配。

我们已经使用了 @ControllerAdvice 注释的处理程序配置。这里有一个片段:

@ControllerAdvice
public class ExceptionHandler {

    @ResponseStatus(code = HttpStatus.NOT_FOUND)
    @ApiResponse(responseCode = "404", description = "(NOT FOUND) Resource does not exist!", content = @Content)
    @ExceptionHandler(NotFoundException.class)
    public void handleException(NotFoundException e) {
        log.warn("Returning {} due to a NotFoundException: {}", HttpStatus.NOT_FOUND, e.toString());
    }

    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ApiResponse(responseCode = "400", description = "(BAD REQUEST) Given resource is invalid!", content = @Content)
    @ExceptionHandler(InvalidResourceException.class)
    public void handleException(InvalidResourceExceptione) {
        log.error("Invalid resource: {}", e.toString());
    }

生成的 API 现在将所有定义的 ApiResponse 显示为所有控制器和端点的响应。因此,我使用 @ControllerAdvice(basePackageClasses = MyController.class) 拆分处理程序配置以对可能的异常进行分组。但仍有一些响应不适合控制器的所有端点。喜欢:

@RestController
public class MyController {

    @ResponseStatus(HttpStatus.CREATED)
    @Operation(summary = "Create", description = "Create myResource!")
    @PostMapping(value = "/myResources/", produces = {"application/json"})
    @ResponseBody
    public Integer create(@RequestBody MyResource newResource) throws InvalidResourceException {
        return creationService.createResource(newResource).getId();
    }

    @ResponseStatus(HttpStatus.OK)
    @Operation(summary = "Update", description = "Update myResource!")
    @PutMapping(value = "/myResources/{id}", produces = {"application/json"})
    public void update(@PathVariable("id") Integer id, @RequestBody MyResource newResource)
            throws ResourceNotFoundException, InvalidResourceException {
        return updateService.updateResource(id, newResource);
    }

    @ResponseStatus(HttpStatus.OK)
    @Operation(summary = "Get", description = "Get myResource!")
    @GetMapping(value = "/myResources/{id}", produces = {"application/json"})
    @ResponseBody
    public MyResource get(@PathVariable("id") Integer id) throws ResourceNotFoundException {
        return loadingService.getResource(id);
    }
}

POST 永远不会用我的“业务”404 响应,GET 永远不会用我的“业务”400 响应。是否可以注释端点,以便在 API 中隐藏不可能的响应代码?

我试图覆盖响应,但没有按预期工作:

    @ResponseStatus(HttpStatus.OK)
    @Operation(summary = "Get", description = "Get myResource!")
    @ApiResponses({@ApiResponse(responseCode = "200", description = "(OK) Returning myResource"),
            @ApiResponse(responseCode = "404", description = "(NOT FOUND) Resource does not exist!")})
    @GetMapping(value = "/myResources/{id}", produces = {"application/json"})
    @ResponseBody
    public MyResource get(@PathVariable("id") Integer id) throws ResourceNotFoundException {
        return loadingService.getResource(id);
    }

400仍然出现...

标签: spring-bootspringdoc-openapi-ui

解决方案


@ApiResponse正如您所提到的,您需要从您的类中删除,@ControllerAdvice并需要在您的控制器类中添加相应的响应。

@ResponseStatus(HttpStatus.OK)
@Operation(summary = "Get", description = "Get myResource!")
@ApiResponses({@ApiResponse(responseCode = "200", description = "(OK) Returning myResource"),
@ApiResponse(responseCode = "404", description = "(NOT FOUND) Resource does not exist!")})
@GetMapping(value = "/myResources/{id}", produces = {"application/json"})
@ResponseBody
public MyResource get(@PathVariable("id") Integer id) throws ResourceNotFoundException {
        return loadingService.getResource(id);
}

推荐阅读