我绘画了一个比较简单的思维图
可以清晰的看到我们需要操作的步骤。
注:先说明我的各个maven依赖版本
<!-- springboot 2.2.2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud Hoxton.SR1 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- spring cloud alibaba 2.1.0.RELEASE -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
我是创建了一个公共了common微服务,给其它微服务Maven引入。
<!--swagger 2.8.0-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger ui 2.8.0-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Created by Administrator on 2022/4/6.
*/
@Configuration
@EnableSwagger2 //开启swagger注解
public class SwaggerConfig {
@Bean
public Docket webApiConfig() {
return new Docket(DocumentationType.SWAGGER_2)
//.groupName("system") // 组名
.apiInfo(webApiInfo())
//.host("8111") // 端口号
.select()
//.paths(Predicates.not(PathSelectors.regex("/admin/.*")))
// 扫描的路径包
.apis(RequestHandlerSelectors.basePackage("com.hch"))
//.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
// 指定路径处理PathSelectors.any()代表所有的路径
.paths(PathSelectors.any())
.build();
}
// 自定义swagger数据源
private ApiInfo webApiInfo() {
return new ApiInfoBuilder()
.title("mall_hch")
.description("本文档描述了微服务各个模块接口定义")
.version("1.0")
.contact(new Contact("java", "", ""))
.build();
}
}
此时启动服务,在网页输入 http://localhost:端口号/swagger-ui.html 应该可以访问了。
但是我们如何配置只用一个swagger文档的路径,查询到对多个微服务模块文档内容呢?
我这里使用的是gateway,好我们继续配置gateway。
<!--swagger 1.9.1.RELEASE-->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.1.RELEASE</version>
</dependency>
<!-- gateway 2.2.1 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启服务发现,可以找到路由
routes:
#region--------------- /swagger/*/** -------------- 转发mall-user微服务模块swagger请求路由
- id: mall-user-swagger
predicates: Path=/swagger/mall-user/**
uri: lb://mall-user
filters:
# 截掉前2个请求路径 例如: 8111/api/test/admin/get --> 8111/admin/get
- StripPrefix=2
#region------------- small-user -------------- 转发mall-user微服务模块
- id: mall-user
predicates: Path=/api/mall-user/**
uri: lb://mall-user
# 使用nacos为注册中心
nacos:
discovery:
server-addr: 101.xx.xxx.xxx:8848
#允许覆盖已经存在的同名bean
#main:
#allow-bean-definition-overriding: true
/**
* Created by HCH on 2022/2/28.
*/
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GatewayMain9527.class, args);
}
}
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import java.util.ArrayList;
import java.util.List;
/**
* //实现SwaggerResourcesProvider,配置swagger接口文档的数据源
* Created by Administrator on 2022/4/7.
*/
@Component
@Primary
public class SwaggerProvider implements SwaggerResourcesProvider {
// 默认访问路径
public static final String API_URI = "/v2/api-docs";
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
public SwaggerProvider(RouteLocator routeLocator, GatewayProperties gatewayProperties) {
this.routeLocator = routeLocator;
this.gatewayProperties = gatewayProperties;
}
@Override
public List<SwaggerResource> get() {
// swagger分组list
List<SwaggerResource> resources = new ArrayList<>();
// yml配置文件路由服务名list
List<String> routes = new ArrayList<>();
// 遍历yml文件 循环添加入list
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
.forEach(routeDefinition -> routeDefinition.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.filter(predicateDefinition-> routeDefinition.getId().contains("swagger"))// 拦截路由服务名,是否包含swagger字符串
.forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("/**", API_URI)))));
return resources;
}
// swagger接口文档的数据源
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;
import java.util.Optional;
/**
* Created by Administrator on 2022/4/7.
*/
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {
@Autowired(required = false)
private SecurityConfiguration securityConfiguration;
@Autowired(required = false)
private UiConfiguration uiConfiguration;
private final SwaggerResourcesProvider swaggerResources;
@Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
}
@GetMapping("/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@GetMapping("/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
}
@GetMapping("")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}