java - OpenApi 文档与 spring-doc 结合 ResponseBodyAdvice

标签 java spring spring-boot springfox springdoc

我有一个简单的 REST API,并且正在测试 springdoc swagger 文档。 其余 Controller :

@RestController
public class UserController {

    private final UserService userService;

    public UserController(final UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/users")
    @PreAuthorize("hasAuthority('create:user')")
    public ResponseEntity<UserDto> create(final @RequestBody @Valid CreateUserCommand command) {
        return ResponseEntity
                .status(HttpStatus.CREATED)
                .body(userService.create(command));
    }
}

然后我将所有 API 响应对象包装在 ResponseControllerAdvice 中:

@RestControllerAdvice
public class CustomResponseBodyAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(final @NotNull MethodParameter returnType,
                            final @NotNull Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(final Object body,
                                  final @NotNull MethodParameter returnType,
                                  final @NotNull MediaType selectedContentType,
                                  final @NotNull Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  final @NotNull ServerHttpRequest request,
                                  final @NotNull ServerHttpResponse response) {
        if (body instanceof ResponseEnvelope || body instanceof Resource) {
            return body;
        }
        if (body instanceof final ResponseEntity<?> responseEntity) {
            response.setStatusCode(responseEntity.getStatusCode());
        }
        return ResponseEnvelope.builder().success(true).result(body).build();
    }

但是我正在努力寻找一种方法让 Springdoc 考虑这个 ResponseEnvelope 包装对象。有什么想法吗?

使用 Spring boot 2.6.2 + Java 17:

            <dependency>
                <groupId>org.springdoc</groupId>
                <artifactId>springdoc-openapi-ui</artifactId>
                <version>1.6.4</version>
            </dependency>

我想要什么:

{
 "status": "OK",
 "result": {
   "username": "johndoe"
   }
 }

我得到了什么:

{
   "username":  "johndoe"
}

最佳答案

使用OperationCustomizer接口(interface)修复了这个问题:

@Configuration
class ApiDocsOperationCustomizer implements OperationCustomizer {

@Override
public Operation customize(Operation operation,
                           HandlerMethod handlerMethod) {
    final Content content = operation.getResponses().get("200").getContent();
    content.keySet().forEach(mediaTypeKey -> {
        final MediaType mediaType = content.get(mediaTypeKey);
        mediaType.schema(this.customizeSchema(mediaType.getSchema()));
    });
    return operation;
}

private Schema<?> customizeSchema(final Schema<?> objSchema) {
    final Schema<?> wrapperSchema = new Schema<>();
    wrapperSchema.addProperties("success", new BooleanSchema()._default(true));
    wrapperSchema.addProperties("result", objSchema);
    return wrapperSchema;
}}

关于java - OpenApi 文档与 spring-doc 结合 ResponseBodyAdvice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70696071/

相关文章:

java - 使 onItemSelected 对整个类(class)可见

java - 如何在jsp中显示位于服务器根目录下的图像

java - 如何触发预定的 Spring Batch Job?

java - Spring Boot 和 Spring Security,无法在 AuthenticationEntryPoint 中使用自定义消息发送错误

java - java中鼠标单击操作事件执行方式错误

java - @PreAuthorize 无法正常工作

java - Spring 启动错误: Use of @OneToMany or @ManyToMany targeting an unmapped class

java - 关于如何将 spring mvc 重构为普通 servlet 或 jetty handler 的建议

spring-boot - 如何使用 JWT 在 Spring Boot 中获取刷新 token

java - Spring Boot 和 Thymeleaf 中的单表继承