栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring-cloud-gateway聚合swagger文档

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring-cloud-gateway聚合swagger文档

需求背景

spring cloud搭建微服务系统,每个业务模块使用swagger开放文档接口查询,在业务网关模块提供swagger文档聚合查询接口,可以通过选择业务模块分类查看。

框架选型、版本及主要功能
  1. spring boot 2.1.6.RELEASE
  2. spring cloud Greenwich.SR3
  3. spring cloud gateway 2.1.3.RELEASE 网关组件
  4. knife4j 2.0.1 增强swagger ui样式,网关使用其starter依赖
  5. swagger bootstrap ui 1.9.6 增强swagger ui样式
  6. spring4all-swagger 1.9.0.RELEASE 配置化swagger参数,免去代码开发
模块职责划分
  1. swagger组件
    开发一个项目内的swagger-spring-boot-starter,整合swagger bootstrap ui 1.9.6和spring4all-swagger 1.9.0.RELEASE,对外提供@EnableSwagger注解服务

  2. 业务模块
    引用自定义的swagger-spring-boot-starter,同时在配置文件中添加本模块的swagger基础信息配置。

  3. 网关模块
    引用knife4j整合swagger,并开发filter、handler、config对多模块的swagger进行聚合

开发步骤示例 swagger组件

pom.xml文件依赖


	com.github.xiaoymin
	swagger-bootstrap-ui
	1.9.6


	com.spring4all
	swagger-spring-boot-starter
	1.9.0.RELEASE

自定义注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@documented
@EnableSwagger2Doc
@EnableSwaggerBootstrapUI
@import(SwaggerCommandLineRunner.class)
public @interface EnableSwagger {
}

注意@EnableSwagger2Doc,@EnableSwaggerBootstrapUI注解,@EnableSwagger2Doc注解能将swagger配置文档化,避免业务模块再开发swagger的代码,@EnableSwaggerBootstrapUI就是改进了swagger ui界面。

指定swagger的默认访问端口

@Slf4j
@Component
public class SwaggerCommandLineRunner implements CommandLineRunner {

    @Value("${server.port:8080}")
    private String serverPort;

    @Override
    public void run(String... args) {
 log.info("swagger url:http://localhost:" + serverPort + "/doc.html");
    }
}

这样这个组件就集成完毕了,这个组件以多module的形式存在于项目公共组件中,使用maven引用即可。

业务模块开发

application中使用@EnableSwagger注解(自行开发的那个,不要搞错了)

@SpringBootApplication
@EnableDiscoveryClient
@MapperScan("com.hy.demo.**.mapper")
@EnableSwagger
public class DemoApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);
		ctx.start();
	}

}

配置文件加上swagger信息:

swagger:
  enabled: true
  title: hy demo
  base-package: com.hy.demo

如此业务模块部分就完成了,非常简单,代码零侵入

网关开发

网关的开发是重头戏,里面需要集成knife4j(这个框架是swagger bootstrap ui的最终版本,最终版改了个名字,开发是同一个人),并且对请求url进行适配

pom.xml添加swagger的依赖


	com.github.xiaoymin
	knife4j-spring-boot-starter
	2.0.1

配置文件gateway部分,对业务接口配置和swagger配置要单独设置routes,例如:

spring:
  application:
    name: gate
  cloud:
    gateway:
      discovery:
 locator:
   #enabled: true0
   enabled: false
   lower-case-service-id: true
      routes:
 - id: demo
   uri: lb://demo
   predicates:
     - Path=/api/json/hy/demo
@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider {

	private static final String SWAGGER_URI = "/v2/api-docs";

	private final RouteLocator routeLocator;
	private final GatewayProperties gatewayProperties;


	@Override
	public List get() {
		List resources = new ArrayList<>();
		List routes = new ArrayList<>();
		// 只抽取后缀为Swagger的路由信息
		routeLocator.getRoutes().filter(r -> r.getId().endsWith("Swagger")).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("
@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> securityConfiguration() {
		return Mono.just(new ResponseEntity<>(
				Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
	}

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

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

swagger 过滤器示例代码


@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
	private static final String HEADER_NAME = "X-Forwarded-Prefix";

	private static final String SWAGGER_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,SWAGGER_URI)) {
				return chain.filter(exchange);
			}
			String basePath = path.substring(0, path.lastIndexOf(SWAGGER_URI));
			ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
			ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
			return chain.filter(newExchange);
		};
	}
}
业务过滤器修改

由于该组件是业务网关组件,肯定会有通用的过滤器,来完成token校验,身份证识别等功能,记得在这些过滤器将"/v2/api-docs"的URL放行,示例代码:

if (StringUtils.endsWithIgnoreCase(path,"/v2/api-docs")) {
	return chain.filter(exchange);
}
测试验证

启动相应的注册中心、业务模块、网关模块进行验证,验证swagger文档、业务接口的处理能否同时满足。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号