由于项目需要,需要使用Gateway,话不多说直接干
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
踩坑开始,开始是继承父工程,工程里存在spring-boot-starter-web依赖
报错:
Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway at this time. Please remove spring-boot-starter-web dependency.
由于springcloudgateway的内部是通过netty+webflux实现的,webflux实现和springmvc配置依赖冲突。
需要 去除依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
</exclusions>
</dependency>
网上大部分网友给的解决方案是如下操作,但是我的工程显示缺少spring-boot-starter-webflux依赖,所以采用了自己的方式 只祛除>spring-boot-starter-web即可,实际情况实际分析,也有的不需要祛除依赖直接引入即可
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</exclusion>
</exclusions>
</dependency>
由于我的工程是使用的nacos集群,所以依赖里引入nacos注册发现和配置管理的依赖
完整的pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>shuomall-gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>shuomall-gateway</name>
<description>shuomall-gateway</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR5</spring-cloud.version>
</properties>
<dependencies>
<!-- 注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 配置管理-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-web</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- <build>-->
<!-- <plugins>-->
<!-- <plugin>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- </build>-->
</project>
application.properties 配置nacos
spring.cloud.nacos.server-addr=127.0.0.1:8848
spring.application.name=shuomall-gateway
server.port=88
启动类开启注册发现 把shuomall-gateway服务注册到nacos
/**
* 1.开启服务注册发现
*/
@EnableDiscoveryClient
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ShuomallGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ShuomallGatewayApplication.class, args);
}
}
application.yml 配置 实现路径重写
spring:
cloud:
gateway:
routes:
- id: admin_route
uri: lb://renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}
- id:名字自己定义
uri: lb://renren-fast //lb负载均衡 renrenfast 指定负载均衡的服务名称
predicates:
- Path=/api/** //按照路径进行断言,可以再前端项目发送请求时进行设置,添加api路径
filters:
- RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment} //路径重写 满足api路径请求,重写成自定义的路径,根据自己的需求进行定义
至此路由的路径重写已经实现,但是访问前端页面的时候发现有跨域问题
创建java类 ShuomallCorsConfiguration 解决跨域问题
package com.ws.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
@Configuration
public class ShuomallCorsConfiguration {
@Bean
public CorsWebFilter corsWebFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
//配置跨域
//头跨域
corsConfiguration.addAllowedHeader("*");
//请求方式跨域
corsConfiguration.addAllowedMethod("*");
//来源跨域
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.setAllowCredentials(true);
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}
可能存在的问题 包含多个值,说明在解决跨域的问题问题上可能有两个类,需要把另一个注释掉就可以了
如果配置文件是yml格式的注意缩进
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml'
2022-03-12 09:58:11.471 ERROR 4732 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application.yml'
at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load(ConfigFileApplicationListener.java:545) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.loadForFileExtension(ConfigFileApplicationListener.java:494) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.context.config.ConfigFileApplicationListener$Loader.load
注意多路径重写,最详细的路径优先否则报错
{"msg":"invalid token","code":401}
需要把明确路径重写要优先于模糊的路径重写
spring:
cloud:
gateway:
routes:
- id: product_route
uri: lb://shuomall-product
predicates:
- Path=/api/product/**
filters:
- RewritePath=/api/(?<segment>.*),/$\{segment}
- id: admin_route
uri: lb://renren-fast
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*),/renren-fast/$\{segment}
# - id: product_route
# uri: lb://shuomall-product
# predicates:
# - Path=/api/product/**
# filters:
# - RewritePath=/api/(?<segment>.*),/$\{segment}