2020年7月份Springfox 3.0.0发布了,增长了对Webflux、OpenApi 3的支持,适应Gateway,微服务中为方便管理各微服务的接口文档,特此来摸索一下Spring Cloud Gateway集成管理,整个过程没什么代码,简单易用html
一、gradle,一个基于 JVM 的富有突破性构建工具,简化maven的xml繁琐配置
二、nacos,阿里开发的动态服务发现、配置和服务管理平台,appllo不喜欢用就它了
三、knife4j,Java MVC框架集成Swagger生成Api文档的加强解决方案,前身是swagger-bootstrap-ui(swagger2用的好好的为啥要用这玩意???原皮看厌倦了换上新鲜的感受)
四、Spring Cloud版本用的是Hoxton.RELEASE,SpringBoot版本2.2.1.RELEASE
以上gradle、nacos环境自行百度搭建,比较简单,不作赘述了前端
端口分别设置为8081和8082java
server: port: 8081
build.gradle:git
plugins { id 'org.springframework.boot' version '2.2.1.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE' id 'java' } group 'com.asan.cart' version '1.0.0-SNAPSHOT' sourceCompatibility = 1.8 ext { set('springBootVersion', "2.2.1.RELEASE") set('springCloudVersion', "Hoxton.RELEASE") set('alibabaCloudVersion', "2.2.1.RELEASE") } repositories { mavenLocal() maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } } configurations { compile.exclude module: 'tomcat-embed-el' compile.exclude module: 'spring-boot-starter-tomcat' } dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' compile ( /** 微服务api文档,不须要引入前端ui包 */ 'com.github.xiaoymin:knife4j-micro-spring-boot-starter:3.0.2', /** nacos配置中心 */ 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config', /** nacos注册与发现中心 */ 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery', 'org.springframework.boot:spring-boot-starter-web', 'org.springframework.boot:spring-boot-starter-undertow' ) } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springBootVersion}" mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${alibabaCloudVersion}" } }
这里主要就是启动微服务集成knife4j文档,由于tomcat老报错,容器就用的undertow,web默认用的tomcat,若是须要须要使用undertow,增长以下内容排除tomcat依赖:github
configurations { compile.exclude module: 'tomcat-embed-el' compile.exclude module: 'spring-boot-starter-tomcat' }
两个微服务客户端增长一个配置类:web
package com.asan.example.config; import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; 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; @Configuration @EnableSwagger2WebMvc public class Swagger2Config { @Bean public Docket createRestApi(){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.asan.example.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { Contact contact = new Contact("阿三", "http://www.asan.com", "asan@163.com"); return new ApiInfoBuilder() .title("example服务文档") .description("example服务API文档") .contact(contact) .version("1.0") .build(); } }
增长启动类ExampleApplicationredis
package com.asan.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication @EnableDiscoveryClient public class ExampleApplication { public static void main(String[] args) { SpringApplication.run(ExampleApplication.class, args); } }
接着来一个Controller作文档展现:spring
Controller这里本身随便写吧,能看到就行,这里也贴一下吧显得不那么空json
package com.asan.example.controller; import com.alibaba.fastjson.JSON; import com.asan.example.entity.Cat; import com.asan.example.pojo.dto.CatDto; import com.asan.example.pojo.vo.PageResult; import com.asan.example.pojo.vo.ResultVO; import com.asan.example.service.impl.CatServiceImpl; import com.asan.example.util.BeanCopierUtil; import com.asan.example.util.RedisClient; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import tk.mybatis.mapper.entity.Example; @RestController @RequestMapping("/v1/example/cat") @Slf4j public class CatController { @Autowired private CatServiceImpl catService; @Autowired private RedisClient redisClient; @ApiOperation("获取信息") @GetMapping public ResultVO<String> getCat(@ApiParam("主键") @RequestHeader("cid") Integer cid) { Cat cat = catService.selectById(cid); if (cat != null) { // 测试缓存 redisClient.setForTimeMIN("SOA:TEXMPLE:CAT:"+cid.toString(), JSON.toJSONString(cat), 30); } return new ResultVO(cat); } @ApiOperation("新增信息") @PostMapping public ResultVO<String> addCat(@RequestBody CatDto catDto) { Cat cat = new Cat(); BeanCopierUtil.copy(catDto, cat); catService.insert(cat); return new ResultVO(Constants.RESULT_SUCCESS); } @ApiOperation("修改信息") @PutMapping public ResultVO<String> updateCat(@RequestBody CatDto catDto) { Cat cat = new Cat(); BeanCopierUtil.copy(catDto, cat); catService.updateById(cat); return new ResultVO(Constants.RESULT_SUCCESS); } @ApiOperation("删除信息") @DeleteMapping public ResultVO<String> deleteCat(@ApiParam("主键") @RequestHeader("cid") Integer cid) { catService.deleteById(cid); return new ResultVO(Constants.RESULT_SUCCESS); } }
而后复制项目更更名称为cart-service,settings-gradle记得也改下
controller里仅修改了路径和类名CartControllerbootstrap
启动类同样复制一个过来,更名GatewayApplication
build.gradle文件增长依赖
compile ( /** api文档,包含前端ui包 */ 'com.github.xiaoymin:knife4j-spring-boot-starter:3.0.2', /** nacos配置中心 */ 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config', /** nacos注册与发现中心 */ 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery', 'javax.servlet:javax.servlet-api:3.1.0', 'org.springframework.cloud:spring-cloud-starter-gateway' )
下面增长一个配置类
package com.asan.gateway.config; 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.Configuration; import org.springframework.context.annotation.Primary; import springfox.documentation.swagger.web.SwaggerResource; import springfox.documentation.swagger.web.SwaggerResourcesProvider; import springfox.documentation.swagger2.annotations.EnableSwagger2WebFlux; import java.util.ArrayList; import java.util.List; /** * @author Jaakko */ @Configuration @Primary @EnableSwagger2WebFlux public class SwaggerResourceConfig implements SwaggerResourcesProvider { public static final String API_URI = "v2/api-docs"; private final RouteLocator routeLocator; private final GatewayProperties gatewayProperties; public SwaggerResourceConfig(RouteLocator routeLocator, GatewayProperties gatewayProperties) { this.routeLocator = routeLocator; this.gatewayProperties = gatewayProperties; } @Override public List<SwaggerResource> get() { List<SwaggerResource> resources = new ArrayList<>(); List<String> routes = new ArrayList<>(); //获取全部路由的ID routeLocator.getRoutes().subscribe(route -> routes.add(route.getId())); //过滤出配置文件中定义的路由->过滤出Path Route Predicate->根据路径拼接成api-docs路径->生成SwaggerResource 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("**", 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; } }
gateway nacos配置
server: port: 9200 spring: cloud: gateway: #配置路由路径 routes: - id: example uri: lb://example predicates: - Path=/example/** filters: - StripPrefix=1 - id: cart-service uri: lb://cart-service predicates: - Path=/cart-service/** filters: - StripPrefix=1 discovery: locator: #开启从注册中心动态建立路由的功能 enabled: true #使用小写服务名,默认是大写 lower-case-service-id: true
启动两个微服务端,再启动gateway服务
浏览器访问:localhost:9200/doc.html
这里某些依赖手动加进去的,并未实际验证!!!(你可能以为坑,但八九不离十),可能存在兼容问题,大体应该能够,有问题能够留言讨论!!!
效果图这里就不截了,自行玩耍