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
這裏某些依賴手動加進去的,並未實際驗證!!!(你可能以爲坑,但八九不離十),可能存在兼容問題,大體應該能夠,有問題能夠留言討論!!!
效果圖這裏就不截了,自行玩耍