Spring-doc-openapi3实用配置
1.配置swagger使用jwt可以通过编程式实现,也可以通过注解式实现,我这里拿注解式举例@SpringBootConfiguration@OpenAPIDefinition(info = @Info(title = "API", version = "v1"))@SecurityScheme(name = "token",type = SecuritySchemeType.HTTP,beare
1.配置swagger使用jwt
可以通过编程式实现,也可以通过注解式实现,我这里拿注解式举例
@SpringBootConfiguration
@OpenAPIDefinition(info = @Info(title = "API", version = "v1"))
@SecurityScheme(
name = "token",
type = SecuritySchemeType.HTTP,
bearerFormat = "JWT",
scheme = "bearer")
public class OpenApiConfig {}
按照Spring官网的介绍,如果要在controller或者方法使用上述jwt认证,需要在controller或者方法级别都添加@SecurityRequirement(name = "token")这样的注解,我这边实现方式如下:
@SecurityRequirement(name = "token")
public interface SecuredRestController {}
定义如上接口,需要认证的Controller实现SecuredRestController。
2.配置自定义生成OperationId
之所以要自定义配置是由于SpringDocOpenApi生成operationId的规则是根据Controller中方法注解或者方法名生成,如果没有注解则用方法名,当多个controller中都有同名方法时候则operationId就变成method_1这种,例如update_1/update_2等等。而且每次顺序都说不是固定的,每次重启该id可能会变。不利于前端根据该文档动态生成代码。
SpringDoc中生成OperationId的逻辑在
org.springdoc.api.AbstractOpenApiResource#calculatePath(org.springframework.web.method.HandlerMethod, org.springdoc.core.fn.RouterOperation)
这个方法中生成Operation以后有个customiseOperation方法,允许对operation自定义,所以自定义一个bean即可,例如我是将operationId改成类名_方法名,这个要求同一个类中不能有同名方法。
@Bean
public OperationCustomizer operationCustomizer() {
return (operation, handlerMethod) -> {
operation.setOperationId(
String.format(
"%s_%s",
handlerMethod.getMethod().getDeclaringClass().getSimpleName(),
handlerMethod.getMethod().getName()));
return operation;
};
}
3.自定义返回值解析
我们在controller返回时候有ControllerAdvice给包装返回值为固定格式的对象,openApi默认生成的文档中是不包含该包装对象的,生成返回值类型代码在如下方法中
org.springdoc.core.GenericResponseBuilder#buildApiResponses(io.swagger.v3.oas.models.Components, org.springframework.core.MethodParameter, io.swagger.v3.oas.models.responses.ApiResponses, org.springdoc.core.MethodAttributes, java.lang.String, io.swagger.v3.oas.models.responses.ApiResponse, boolean)
跟踪代码看到最终是通过
org.springdoc.core.GenericResponseBuilder#getReturnType
该方法返回的,这里的ReturnTypeParser是没有任何实现的,通过
org.springdoc.core.SpringDocConfiguration#genericReturnTypeParser
该方法初始化的,所以自定义一个ReturnTypeParser Bean即可。
实现如下:
@Bean
public ReturnTypeParser customReturnTypeParser() {
return new ReturnTypeParser() {
@Override
public Type getReturnType(MethodParameter methodParameter) {
Type returnType = ReturnTypeParser.super.getReturnType(methodParameter);
Annotation[] annotations =
Objects.requireNonNull(methodParameter.getMethod())
.getDeclaringClass()
.getAnnotations();
if (Arrays.stream(annotations)
.noneMatch(annotation -> annotation instanceof RestController)) {
return returnType;
}
if (returnType.getTypeName().equals("void")) {
return returnType;
}
return TypeUtils.parameterize(ServerResponse.class, returnType);
}
};
}
其中ServerResponse就是ControllerAdvice中对返回值的包装类型。
4.SpringDocOpenApi官方文档地址
更多推荐
所有评论(0)