OpenApi文档与spring文档结合ResponseBodyAdvice



我有一个简单的rest API,我正在测试springdoc swagger文档。其余控制器:

@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包装器对象。有什么想法吗?

使用Springboot2.6.2+Java17:

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

我想要什么:

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

我得到的:

{
"username":  "johndoe"
}

使用OperationCustomizer接口修复了它:

@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;
}}

最新更新