网关集成swagger

This commit is contained in:
xiongxiaoyang 2021-04-03 20:44:38 +08:00
parent b143b7c634
commit 7bed818730
7 changed files with 236 additions and 2 deletions

View File

@ -0,0 +1,68 @@
management: #开启SpringBoot Admin的监控
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
server:
port: 527
spring:
cloud:
nacos:
discovery:
server-addr: 47.106.243.172:8848
namespace: 3960c71a-62ac-4b8f-8c30-bba8e8143a0c
gateway:
routes:
- id: home-route
uri: lb://novel-home
predicates:
- Path=/api/home/**
filters:
#注意过滤器按顺序执行,下面的顺序不能打乱
- SwaggerFilter
- RewritePath=/api/(?<segment>.*), /$\{segment}
- id: news-route
uri: lb://news-service
predicates:
- Path=/api/news/**
filters:
#注意过滤器按顺序执行,下面的顺序不能打乱
- SwaggerFilter
- RewritePath=/api/(?<segment>.*), /$\{segment}
- id: user-route
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
#注意过滤器按顺序执行,下面的顺序不能打乱
- SwaggerFilter
- RewritePath=/api/(?<segment>.*), /$\{segment}
- id: book-route
uri: lb://book-service
predicates:
- Path=/api/book/**
filters:
#注意过滤器按顺序执行,下面的顺序不能打乱
- SwaggerFilter
- RewritePath=/api/(?<segment>.*), /$\{segment}
- id: search-route
uri: lb://novel-search
predicates:
- Path=/api/search/**
filters:
#注意过滤器按顺序执行,下面的顺序不能打乱
- SwaggerFilter
- RewritePath=/api/(?<segment>.*), /$\{segment}
- id: monitor-route
uri: lb://novel-monitor
predicates:
- Path=/monitor/**
filters:
- RewritePath=/monitor/(?<segment>.*), /$\{segment}

View File

@ -45,6 +45,24 @@
<artifactId>sentinel-transport-simple-http</artifactId> <artifactId>sentinel-transport-simple-http</artifactId>
</dependency> </dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies> </dependencies>

View File

@ -0,0 +1,38 @@
package com.java2nb.novel.gateway.swagger;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
/**
* swagger过滤器重新设置单个微服务接口文档的路径和接口的基础请求路径
* 如果要让网关的swagger生效一定要在每个微服务路由配置的过滤器filters首行配置上SwaggerFilter
* 因为filters下的过滤器按顺序执行所以一定要注意顺序只能放到首行
* @author xiongxiaoyang
* @version 1.0
* @since 2021/4/3
*/
@Component
public class SwaggerFilter extends AbstractGatewayFilterFactory {
private static final String HEADER_NAME = "X-Forwarded-Prefix";
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
return chain.filter(exchange);
}
//重新设置doc文档的路径断言先执行不影响已经断言到的服务
ServerHttpRequest.Builder build = request.mutate().path("/api"+SwaggerProvider.API_URI);
//设置接口的基础请求路径
ServerHttpRequest newRequest = build.header(HEADER_NAME, "/api").build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange);
};
}
}

View File

@ -0,0 +1,48 @@
package com.java2nb.novel.gateway.swagger;
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.*;
/**
* swagger handler
* @author xiongxiaoyang
* @version 1.0
* @since 2021/4/3
*/
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {
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<>(
SecurityConfigurationBuilder.builder().build(), HttpStatus.OK));
}
@GetMapping("/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
UiConfigurationBuilder.builder().build(), HttpStatus.OK));
}
@GetMapping("")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}

View File

@ -0,0 +1,57 @@
package com.java2nb.novel.gateway.swagger;
import lombok.AllArgsConstructor;
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;
/**
* swagger provider设置需要由网关管理的微服务资源名和路径
* @author xiongxiaoyang
* @version 1.0
* @since 2021/4/3
*/
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {
public static final String API_URI = "/v2/api-docs";
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
//取出gateway的route
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
//结合配置的route-路径(Path)和route过滤只获取有效的route节点
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
.forEach(routeDefinition ->
routeDefinition.getPredicates().stream()
.filter(
predicateDefinition ->
("Path").equalsIgnoreCase(predicateDefinition.getName()) && predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0").startsWith("/api/"))
.forEach(
predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("/**", API_URI)))));
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}

View File

@ -9,6 +9,11 @@ spring:
file-extension: yml file-extension: yml
group: ${spring.application.name} group: ${spring.application.name}
namespace: 3960c71a-62ac-4b8f-8c30-bba8e8143a0c namespace: 3960c71a-62ac-4b8f-8c30-bba8e8143a0c
#关闭Spring自带的X-Forwarded-Prefix设置
gateway:
x-forwarded:
prefix-enabled: false
main: main:
allow-bean-definition-overriding: true allow-bean-definition-overriding: true

View File

@ -42,7 +42,7 @@
<spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>
<openfeign.version>2.2.0.RELEASE</openfeign.version> <openfeign.version>2.2.0.RELEASE</openfeign.version>
<nacos.version>0.2.2.RELEASE</nacos.version> <nacos.version>0.2.2.RELEASE</nacos.version>
<swagger.version>2.7.0</swagger.version> <swagger.version>2.9.2</swagger.version>
<maven.test.skip>true</maven.test.skip> <maven.test.skip>true</maven.test.skip>
<mysql.version>8.0.11</mysql.version> <mysql.version>8.0.11</mysql.version>
<mybatis.version>1.3.2</mybatis.version> <mybatis.version>1.3.2</mybatis.version>