实现Spring Cloud Alibaba ,Gateway集成Knife4j
本篇博客主要讲解通过knife4j项目如何集成Spring Cloud Gateway网关,通过网关聚合所有的Swagger微服务文档
源码地址:https://gitee.com/xiaoym/swagger-bootstrap-ui-demo/tree/master/knife4j-spring-cloud-gateway
官方文档:https://doc.xiaominfo.com/knife4j/action/springcloud-gateway.html
源码整体项目结构如下:
|-knife4j-spring-cloud-gateway
|-----service-doc //文档聚合中心,是所有微服务文档的出口
|-----service-order //订单服务,包含所有与订单业务模块相关的接口
|-----service-server //eureka 注册中心
|-----service-user //用户服务,包含所有的用户接口
Alibaba就不要用到eureka
Nacos的配置和
Eureka
几乎一模一样,唯一不同的区别是在yml进行配置的时候,使用的是
knife4j.nacos
开头,其他基本都是一样,所以就只要用到这两个模块即可:
|-----service-doc //文档聚合中心,是所有微服务文档的出口
|-----service-order //订单服务,包含所有与订单业务模块相关的接口
以下的application.yaml都是从作者自己项目里复制过来的,可以根据自己的实际情况改一下
service-doc
源码地址:https://gitee.com/xiaoym/swagger-bootstrap-ui-demo/blob/master/knife4j-spring-cloud-gateway/service-order/src/main/java/com/xiaominfo/swagger/service/order/config/SwaggerConfiguration.java
对应Spring Cloud内有controller的模块块:
package com.xiaominfo.swagger.service.order.config;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.annotation.Order;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
import java.util.List;
@Configuration
@EnableSwagger2WebMvc
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfiguration {
@Bean(value = "orderApi")
@Order(value = 1)
public Docket groupRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(groupApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.xiaominfo.swagger.service.order.controller"))
.paths(PathSelectors.any())
.build().securityContexts(CollectionUtils.newArrayList(securityContext(),securityContext1())).securitySchemes(CollectionUtils.<SecurityScheme>newArrayList(apiKey(),apiKey1()));
}
private ApiInfo groupApiInfo(){
return new ApiInfoBuilder()
.title("swagger-bootstrap-ui很棒~~~!!!")
.description("<div style='font-size:14px;color:red;'>swagger-bootstrap-ui-demo RESTful APIs</div>")
.termsOfServiceUrl("http://www.group.com/")
.contact("group@qq.com")
.version("1.0")
.build();
}
private ApiKey apiKey() {
return new ApiKey("BearerToken", "Authorization", "header");
}
private ApiKey apiKey1() {
return new ApiKey("BearerToken1", "Authorization-x", "header");
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex("/.*"))
.build();
}
private SecurityContext securityContext1() {
return SecurityContext.builder()
.securityReferences(defaultAuth1())
.forPaths(PathSelectors.regex("/.*"))
.build();
}
List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return CollectionUtils.newArrayList(new SecurityReference("BearerToken", authorizationScopes));
}
List<SecurityReference> defaultAuth1() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
return CollectionUtils.newArrayList(new SecurityReference("BearerToken1", authorizationScopes));
}
}
application.yaml日常用的yaml文件
spring:
application:
name: bank-accounts
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.211.130:3306/onlinebank?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: 123456
hikari:
pool-name: dataHikariCP
minimum-idle: 5
# 默认十分钟
idle-timeout: 180000
maximum-pool-size: 10
max-lifetime: 180000
auto-commit: true
connection-timeout: 30000
connection-test-query: SELECT 1
cloud:
nacos:
discovery:
server-addr: 192.168.211.130:8848
username: nacos
password: nacos
server:
port: 8881
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: false
type-aliases-package: com.lsy.bank.entity
mapper-locations: classpath*:/mapper/*Mapper.xml
#
#swagger:
# enabled: true
# title: 用户服务
# base-package: com.lsy.bank.controller
# version: V2.0
# description: 用户服务
# license: Apache License, Version 2.0
# license-url: https://www.apache.org/licenses/LICENSE-2.0.html
# terms-of-service-url: http://localhost:8881/doc.html
# contact: xxxxxxxxxxxx@gmail.com
# authorization: #有auth2 并使用以前的swagger-ui
# key-name: Authorization
knife4j:
production: false
pom.xml
https://gitee.com/xiaoym/swagger-bootstrap-ui-demo/blob/master/knife4j-spring-cloud-gateway/service-order/pom.xml
<dependencies>
<!--knife4j-micro-包含swagger2依赖-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入服务注册的依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.6</version>
</dependency>
<!-- @EnableSwagger2WebMvc注解要用 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.10.5</version>
</dependency>
<!-- 没有会报错原因讲不清楚 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
</dependencies>
ServiceOrderApplication
@EnableEurekaClient
@SpringBootApplication
public class ServiceOrderApplication {
}
service-order
对应gateway
https://gitee.com/xiaoym/swagger-bootstrap-ui-demo/tree/master/knife4j-spring-cloud-gateway/service-doc/src/main/java/com/xiaominfo/swagger/service/doc
原封不动搬过来就可以用了
ServiceDocApplication
@SpringBootApplication
public class ServiceDocApplication {
}
application.yaml (主要是网关,最后导致出不来可能是这个原因)
server:
port: 8888
spring:
application:
name: bank-gateway
cloud:
nacos:
discovery:
server-addr: 192.168.211.130:8848
gateway:
discovery:
locator:
enabled: true
routes:
- id: bank-accounts
uri: lb://bank-accounts
predicates:
- Path=/account/**
filters:
- SwaggerHeaderFilter #指定filter
- StripPrefix=1
- id: bank-records
uri: lb://bank-records
predicates:
- Path=/records/**
filters:
- SwaggerHeaderFilter #指定filter
- StripPrefix=1
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--引入服务注册的依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--alibaba在2020版之后不使用ribbon,这里使用loadbalancer代替,然后在配置文件中禁用ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
报错
看着官方文档写下来遇到两个头疼的问题
1.跨域报错
报错:When allowCredentials is true, allowedOrigins cannot contain the special value
将之前写的的
.allowedOrigins("*")
替换为
.allowedOriginPatterns("*")
即可。
2.版本问题
这是由于版本不兼容引发的问题,我当前使用的springcloud alibaba版本为
2021.0.1.0
,而springcloud alibaba在2020版之后不支持ribbon,而springcloud gateway使用ribbon,就导致了gateway无法路由到目标服务,这里可以使用loadbalancer代替,然后在配置文件中禁用ribbon,修改后的配置与依赖如下:
<!--alibaba在2020版之后不使用ribbon,这里使用loadbalancer代替,然后在配置文件中禁用ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
ibbon,而springcloud gateway使用ribbon,就导致了gateway无法路由到目标服务,这里可以使用loadbalancer代替,然后在配置文件中禁用ribbon,修改后的配置与依赖如下:
<!--alibaba在2020版之后不使用ribbon,这里使用loadbalancer代替,然后在配置文件中禁用ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>