adn*_*n_e 4 spring-boot springfox spring-webflux
我正在使用 springfox 3.0.0 进行反应式支持,并@EnableSwagger2WebFlux在我的 swagger 配置中使用。
我的招摇配置如下:
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage(basePackage))
.paths(PathSelectors.any())
.build()
.securityContexts(Lists.newArrayList(securityContext()))
.securitySchemes(Lists.newArrayList(apiKey()))
.globalOperationParameters(operationParameters());
}
Run Code Online (Sandbox Code Playgroud)
我有一个简单的控制器,如下所示:
@CrossOrigin(origins = "*", allowedHeaders = "*", maxAge = 3600)
@RestController
@RequestMapping("/")
public class ApiController {
@ApiOperation(value = "get all partners", authorizations = {@Authorization(value = "Bearer")})
@RequestMapping(value = "/partner",
method = RequestMethod.GET,
produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Request succeeded")
})
public Mono<ResponseEntity<Flux<PartnerDTO>>> getAllPartners(
@ApiIgnore ServerHttpRequest httpRequest
) {
return ...
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以通过在@ApiOperation 中指定响应类型来解决这个问题,但我试图避免这种情况,例如
@ApiOperation(value = "get all partners", authorizations = {@Authorization(value = "Bearer")})
@RequestMapping(value = "/partner",
method = RequestMethod.GET,
produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}
)
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Request succeeded", response = PartnerDTO.class)
})
public Mono<ResponseEntity<Flux<PartnerDTO>>> getAllPartners(
@ApiIgnore ServerHttpRequest httpRequest
) {
Run Code Online (Sandbox Code Playgroud)
我不喜欢这种方法,因为它是一个手动过程,因此容易出错。我想要一些自动方式来进行以下转换:
Flux<T> -> T[] (since flux emits 0...N elements)
Mono<T> -> T
ResponseEntity<T> -> T
Run Code Online (Sandbox Code Playgroud)
当然,它必须是递归的(例如Mono<ResponseEntity<Flux<T>>> -> T)。
我浏览了 springfox 的代码,试图找到一些自定义类型解析的入口点,幸运的是它有一个HandlerMethodResolver可以从外部注入的代码。
我在我的 swagger 配置类中添加了这个解析器的自定义实现:
@Bean
@Primary
public HandlerMethodResolver fluxMethodResolver(TypeResolver resolver) {
return new HandlerMethodResolver(resolver) {
@Override
public ResolvedType methodReturnType(HandlerMethod handlerMethod) {
var retType = super.methodReturnType(handlerMethod);
// we unwrap Mono, Flux, and as a bonus - ResponseEntity
while (
retType.getErasedType() == Mono.class
|| retType.getErasedType() == Flux.class
|| retType.getErasedType() == ResponseEntity.class
) {
if ( retType.getErasedType() == Flux.class ) {
// treat it as an array
var type = retType.getTypeBindings().getBoundType(0);
retType = new ResolvedArrayType(type.getErasedType(), type.getTypeBindings(), type);
} else {
retType = retType.getTypeBindings().getBoundType(0);
}
}
return retType;
}
};
}
Run Code Online (Sandbox Code Playgroud)
这正是我需要的。
它会自动转换Mono<ResponseEntity<Flux<PartnerDTO>>>到PartnerDTO[],并Mono<ResponseEntity<Mono<PartnerDTO>>>到PartnerDTO。
编辑::我更改了这个实现以将 Flux 转换为 T[],因为它从一开始就应该如此。
| 归档时间: |
|
| 查看次数: |
2047 次 |
| 最近记录: |