当前位置:网站首页>Small tools (3) integration knife4j3.0.3 interface document
Small tools (3) integration knife4j3.0.3 interface document
2022-06-30 17:56:00 【Zheng Qing】
List of articles
One 、 Preface
This article will integrate knife4j-spring-boot-starter3.0.3
Interface document & gateway Aggregate service interface documents & Integrate oauth2 Password mode for authorized authentication login
<spring-boot.version>2.6.7</spring-boot.version>
<spring-cloud.version>2021.0.1</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
There will be swagger The document is separately extracted from a common module for unified management
Two 、swagger Common module extraction
1、 Introduce dependencies
<!-- knife4j -->
<!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-spring-boot-starter -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
2、Knife4j Configuration class
tips: What we use here is swagger2.0 Of api Document mode , Because in 3 Integrated inside oauth2 Authentication found that there is no form authentication login , Not very friendly , I haven't seen any official documents , If you find something later , Update to Xiaobian's demo Source code
^_^
@Slf4j
@Configuration
@EnableSwagger2WebMvc
// Yes JSR303 Provide support
@Import(BeanValidatorPluginsConfiguration.class)
public class Knife4jConfig {
@Value("${spring.application.name}")
private String applicationName;
@Value("${small-tools.ip}")
private String ip;
@Value("${server.port}")
private String port;
@Value("${knife4j.passwordTokenUrl}")
private String passwordTokenUrl;
@Resource
private OpenApiExtensionResolver openApiExtensionResolver;
@Bean
public Docket defaultApi() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(this.apiInfo())
.groupName(this.applicationName)
.select()
// add to @Api Notes are displayed
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
// .apis(RequestHandlerSelectors.basePackage("com.zhengqing"))
.paths(PathSelectors.any())
.build()
// Plug in extensions -- ex: Customize md file
.extensions(this.openApiExtensionResolver.buildExtensions(this.applicationName))
// Default global parameters
.globalRequestParameters(
Lists.newArrayList(
new RequestParameterBuilder()
.name(SwaggerConstant.TENANT_ID)
.description(" Tenant ID")
.in(ParameterType.HEADER)
.required(true)
.build()
)
);
// context
List<SecurityContext> securityContexts = Lists.newArrayList(
SecurityContext.builder()
.securityReferences(
CollectionUtil.newArrayList(
new SecurityReference("oauth2",
Lists.newArrayList(
new AuthorizationScope("read", "read resources"),
new AuthorizationScope("write", "write resources"),
new AuthorizationScope("reads", "read all resources"),
new AuthorizationScope("writes", "write all resources")
).toArray(new AuthorizationScope[]{
})
)
)
)
.forPaths(PathSelectors.ant("/**"))
.build()
);
// Password mode
List<SecurityScheme> securitySchemes = Lists.newArrayList(
new OAuthBuilder()
.name("oauth2")
.grantTypes(Lists.newArrayList(new ResourceOwnerPasswordCredentialsGrant(this.passwordTokenUrl)))
.build()
);
docket.securityContexts(securityContexts).securitySchemes(securitySchemes);
return docket;
}
/** * swagger-api Interface description information */
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("API file ")
.description("API file ")
.termsOfServiceUrl(String.format("%s:%s/", this.ip, this.port))
.contact(
new Contact(
"zhengqingya",
"https://gitee.com/zhengqingya",
"[email protected]"
)
)
.version("1.0.0")
.build();
}
/** * solve Spring Boot 2.6.x above And Swagger 3.0.0 Incompatibilities * Reference resources https://github.com/springfox/springfox/issues/3462 */
@Bean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
ServletEndpointsSupplier servletEndpointsSupplier,
ControllerEndpointsSupplier controllerEndpointsSupplier,
EndpointMediaTypes endpointMediaTypes,
CorsEndpointProperties corsProperties,
WebEndpointProperties webEndpointProperties,
Environment environment) {
List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
allEndpoints.addAll(webEndpoints);
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
String basePath = webEndpointProperties.getBasePath();
EndpointMapping endpointMapping = new EndpointMapping(basePath);
boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
}
private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
}
}
3、application-swagger.yml
spring:
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER # solve springboot Higher version Knife4j Report the wrong question
# https://doc.xiaominfo.com/knife4j
knife4j:
# Turn on enhanced configuration
enable: true
# Whether the production environment shielding is enabled true: close swagger,false: Turn on swagger
production: false
# Custom document
documents:
- group: demo
name: Test custom header grouping
# All under a folder .md file
locations: classpath:markdown/*
# Turn on Swagger Of Basic Authentication function , The default is false
basic:
# Whether to turn on authentication
enable: false
# Basic Authentication user name
username: admin
# Basic The authentication code
password: 123456
passwordTokenUrl: http://127.0.0.1:1218/auth/oauth/token # Gateway service api
# passwordTokenUrl: http://127.0.0.1:1219/oauth/token # Authorized service api
3、 ... and 、 Microservice interface documents
1、 introduce swagger Common module
2、 Service module bootstrap.yml
Fill in the basic information of each service ( port 、 Application name …)
3、 Public infrastructure bootstrap.yaml
Here, we extract the public configurations required by each service to bootstrap.yaml
It is convenient to manage all micro service configurations in a unified way
tips: yml The priority of the configuration file is from high to low
bootstrap.yml
>bootstrap.yaml
>application.yml
In this project
Basic public configuration :small-tools-api/common/web/src/main/resources/bootstrap.yaml
=> Basic component configuration
Other module configurations :small-tools-api/service/system/src/main/resources/bootstrap.yml
=> Ports of each module 、 Application name, etc
Four 、Gateway Aggregate interface documentation
1、 Introduce dependencies
<!-- knife4j -->
<!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-spring-boot-starter -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
2、 Dynamically aggregate the services swagger Interface
@Primary
@Component
public class MySwaggerResourcesProvider implements SwaggerResourcesProvider {
/** * swagger default url suffix * {@link com.zhengqing.common.swagger.config.Knife4jConfig} */
private static final String SWAGGER_URL = "/v2/api-docs?group=";
/** * nacos Registry Center */
@Resource
private DiscoveryClient discoveryClient;
/** * Gateway application name */
@Value("${spring.application.name}")
private String gatewayServiceName;
@Override
public List<SwaggerResource> get() {
// swagger Drop down list service resources
List<SwaggerResource> resourceList = new ArrayList<>();
// Get dynamic nacos Service instance name on the registry
List<String> nacosServiceNameList = this.discoveryClient.getServices();
for (String instance : nacosServiceNameList) {
String instanceName = instance.toLowerCase();
if (this.gatewayServiceName.equals(instanceName)) {
continue;
}
// Splicing swagger visit url, Style is `/demo/v2/api-info?group=demo`, When the gateway calls this interface , It will automatically find the corresponding host through load balancing
String url = "/" + instanceName + SWAGGER_URL + instanceName;
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setUrl(url);
swaggerResource.setName(instance);
resourceList.add(swaggerResource);
}
return resourceList;
}
}
swagger-ui.html Interface to be accessed
@RestController
@RequiredArgsConstructor
@RequestMapping("/swagger-resources")
public class SwaggerHandler {
private final MySwaggerResourcesProvider mySwaggerResourcesProvider;
/** * Permission processor */
@GetMapping("/configuration/security")
public ResponseEntity<SecurityConfiguration> securityConfiguration() {
return new ResponseEntity<>(SecurityConfigurationBuilder.builder().build(), HttpStatus.OK);
}
/** * UI processor */
@GetMapping("/configuration/ui")
public ResponseEntity<UiConfiguration> uiConfiguration() {
return new ResponseEntity<>(UiConfigurationBuilder.builder().build(), HttpStatus.OK);
}
/** * Aggregation of services swagger Interface */
@GetMapping("")
public ResponseEntity swaggerResources() {
return new ResponseEntity<>(mySwaggerResourcesProvider.get(), HttpStatus.OK);
}
}
This method will dynamically pull us nacos The above registered service names are spliced to access the interface documents of our micro Services
ex:/demo/v2/api-info?group=demo
5、 ... and 、swagger Integrate oauth2 Password mode for authorization authentication
stay swagger Common modules have been introduced oauth2 Certification of
Once the certification is successful , Refreshing the page will refresh automatically Authorization
The value of is convenient for us to test api
What needs to be explained here is that after the authentication interface is authorized successfully Authorization
Value problem
Generally, the back end will have a unified response body
{
"code": 200,
"data": [],
"msg": "OK"
}
When we have a unified response body Authorization
The value will appear undefined undefined
The problem of
We can open the browser to view the front end UI Cache value discovery value tokenType
&accessToken
Go again Knife4j
The front end of the UI Search for relevant values in the source code , You can see that the value logic is
$.post(url,params,function(data){
if(data!=null&&data!=undefined) {
that.cacheValue.accessToken=data.token_type+" "+data.access_token;
that.cacheValue.tokenType=data.token_type;
that.cacheValue.granted=true;
window.localStorage.setItem(that.state,JSON.stringify(that.cacheValue))
window.close();
}
})
Therefore, after our authorization and authentication are successful, the required fields are modified and returned
After recertification Authorization
Value return to normal ^_^
6、 ... and 、 Source code
tips: Recently, projects are refactoring , The latest code is placed in dev Branch up
https://gitee.com/zhengqingya/small-tools
Share today :
No matter when , No matter what , I will never allow myself to be a little discouraged .
边栏推荐
- Compile and generate busybox file system
- 开发那些事儿:如何在视频中添加文字水印?
- Interview shock 60: what will cause MySQL index invalidation?
- Canvas mouse control gravity JS effect
- 巴比特 | 元宇宙每日必读:未成年人打赏后要求退款,虚拟主播称自己是大冤种,怎么看待这个监管漏洞?...
- Cloud practice of key business migration of Internet of things by well-known Internet housing rental service companies
- Plane intersection and plane equation
- Develop those things: how to add text watermarks to videos?
- .NET ORM框架HiSql实战-第一章-集成HiSql
- [sword finger offer] 53 - I. find the number I in the sorted array
猜你喜欢
5g has been in business for three years. Where will innovation go in the future?
MIT科技评论2022年35岁以下创新者名单发布,含AlphaFold作者等
Canvas cloud shape animation
[C language] explain threads - thread separation function pthread_ detach
Thinking on large file processing (upload, download)
Splitting. JS text title slow loading JS effect
6 張圖帶你搞懂 TCP 為什麼是三次握手?
AnimeSR:可学习的降质算子与新的真实世界动漫VSR数据集
Write the simplest small program in C language Hello World
Acwing game 57
随机推荐
【剑指Offer】剑指 Offer 53 - II. 0~n-1中缺失的数字
[C language] explain threads - start two threads
6 張圖帶你搞懂 TCP 為什麼是三次握手?
Flutter custom component
新技能:通过代码缓存加速 Node.js 的启动
5g business is officially commercial. What are the opportunities for radio and television?
MOOG servo valve d661-4577c
Combination of applet container and Internet of things
开发那些事儿:Linux系统中如何安装离线版本MySQL?
2022上半年盘点:20+主流数据库重大更新及技术要点汇总
【义修换届大礼包】
浅析搭建高速公路视频监控平台的建设方案及必要性
理解现货白银走势的关键
自旋锁探秘
[C language] explain threads in detail - solve the problem of shared memory caused by concurrent programs by "locking"
[BJDCTF2020]The mystery of ip|[CISCN2019 华东南赛区]Web11|SSTI注入
[sword finger offer] sword finger offer 53 - ii Missing numbers from 0 to n-1
5G业务正式商用,属于广电的机会在哪?
Interview shock 60: what will cause MySQL index invalidation?
Ten thousand volumes - list sorting [01]