微服务使用knife4j进行在线接口调试

前言

之前发布了一个博客是关于​​SpringBoot​​​使用​​knife4j​​​进行在线接口调试,那是一个单节点下的教程,那么在微服务情况,每一个服务都是一个独立的​​knife4j​​​的话,显然是不方便的,那么对于微服务的情况下,我们如何使用​​knife4j​​呢?

SpringBoot使用knife4j可参考我的博客:​​SpringBoot使用knife4j进行在线接口调试​​

Nacos安装以及其使用可参考我的博客:​​Nacos服务治理中心和配置中心​​

正文

微服务使用knife4j进行在线接口调试

我们这里以微服务使用​​Gateway​​举例,它是由两个模块组成:

  • ​spring-dubbo-gateway​​​:​​Gateway​​模块
  • ​gateway-producer-service​​​:​​producer​​模块

网关模块:spring-dubbo-gateway

注入依赖

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>


<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>


<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>


<!--knife4j接口-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<optional>true</optional>
</dependency>

application.properties:配置文件

server.port=9000
spring.application.name=spring-dubbo-gateway
spring.main.allow-bean-definition-overriding=true


spring.cloud.nacos.discovery.server-addr=127.0.0.7:8848
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
spring.cloud.gateway.routes[0].id=gateway-producer-service
spring.cloud.gateway.routes[0].uri=lb://spring-dubbo-producer
spring.cloud.gateway.routes[0].predicates[0]=Path=/producer/**

#swagger配置
spring.cloud.gateway.routes[0].filters[0] = SwaggerHeaderFilter
spring.cloud.gateway.routes[0].filters[1] = StripPrefix=1
spring.cloud.gateway.x-forwarded.enabled=false

SwaggerResourceConfig.java:Swagger配置类

@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider {
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> {
route.getPredicates().stream() .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0") .replace("**", "v2/api-docs"))));
});
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
log.info("name:{},location:{}",name,location);
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}

SwaggerHandler.java:资源处理类

@RestController
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("/swagger-resources/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
}


@GetMapping("/swagger-resources/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
}


@GetMapping("/swagger-resources")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}

SwaggerHeaderFilter.java:以拦截器的方式管理请求Header

@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
private static final String HEADER_NAME = "X-Forwarded-Prefix";
private static final String URI = "/v2/api-docs";
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path,URI )) {
return chain.filter(exchange);
}
String basePath = path.substring(0, path.lastIndexOf(URI));
ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange);
};
}
}

代理服务模块:spring-dubbo-producer

注入依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
<!--knife4j接口-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<optional>true</optional>
</dependency>

application.properties:配置文件

server.port=8080
spring.application.name=spring-dubbo-producer
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

SwaggerConfig.class:Swagger配置类

/**
* swagger配置
*/
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfig {


/**
* 这里配置swagger扫描的包
* @return
*/
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors
.basePackage("com.luo.producer"))
.paths(PathSelectors.any()).build();
}


/**
* 这里配置swagger对外提供服务的端口
* @return
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("发布模拟boos接口")
.description("简单优雅的发布模拟boos接口restful风格接口")
// .termsOfServiceUrl("http://127.0.0.1:8080/doc.html")
.version("1.0").build();
}
}

验证

启动项目在Nacos可看到服务

微服务使用knife4j进行在线接口调试_gateway

测试接口

@RestController
@Slf4j
@RequestMapping("/producer")
public class UserController {

@GetMapping("/helloword")
public String hello(String input){
return "你好,"+input;
}

}

进入knife4j管理界面进行接口测试

微服务使用knife4j进行在线接口调试_java_02


微服务使用knife4j进行在线接口调试_spring boot_03