API网关
<?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"> <parent> <artifactId>infrastructure</artifactId> <groupId>com.javaclimb</groupId> <version>0.0.1-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>api_gateway</artifactId> <dependencies> <!-- 网关 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!--服务注册--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.javaclimb</groupId> <artifactId>common_util</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 排除 spring-boot-starter-web, 否则和 gateway 中的 webflux 冲突 --> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </exclusion> </exclusions> </dependency> <!--将随着spring-boot-starter-web排除的servlet-api添加回来 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <!--gson--> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
server: port: 8090 spring: profiles: active: dev application: name: infrastructure-apigateway cloud: # nacos 服务 nacos: discovery: server-addr: 127.0.0.1:8848 gateway: discovery: locator: # gateway 可以发现 nacos 中的微服务 enabled: true routes: - id: service-edu # 随便起 # uri: http://localhost:9110 # 目标路由 # 目标路由,必须和 nacos 中微服务名称一样, lb -> 以负载均衡的方式访问 uri: lb://service-edu predicates: # 路径断言,只要这个条件成立,就转发到上面的地址 - Path=/user/**, /*/edu/** - id: service-cms uri: lb://service-cms predicates: - Path=/*/cms/** # 过滤器 filters: - SetStatus=250 # 修改响应状态码为 250 - id: service-oss uri: lb://service-oss predicates: - Path=/*/oss/** - id: service-trade uri: lb://service-trade predicates: - Path=/*/trade/** - id: service-ucenter uri: lb://service-ucenter predicates: - Path=/*/ucenter/** - id: service-vod uri: lb://service-vod predicates: - Path=/*/vod/** - id: service-statistics uri: lb://service-statistics predicates: - Path=/*/statistics/** - id: service-acl uri: lb://service-acl predicates: - Path=/*/acl/**
package com.stu.infrastructure; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; /****************************** * 用途说明: * 作者姓名: Administrator * 创建时间: 2022-07-27 22:56 ******************************/ @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @EnableDiscoveryClient public class ApiGatewayApplication { public static void main(String[] args) { SpringApplication.run(ApiGatewayApplication.class, args); } }
package com.stu.infrastructure.confing; 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.util.pattern.PathPatternParser; /****************************** * 用途说明: * 作者姓名: Administrator * 创建时间: 2022-07-27 23:16 ******************************/ @Configuration public class CorsConfig { @Bean public CorsWebFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); // #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin config.addAllowedOrigin("*"); // #允许访问的头信息,*表示全部 config.addAllowedHeader("*"); // 允许提交请求的方法类型,*表示全部允许 config.addAllowedMethod("*"); org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource source = new org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource(new PathPatternParser()); source.registerCorsConfiguration("/**", config); return new CorsWebFilter(source); } }
package com.stu.infrastructure.filter; /****************************** * 用途说明: * 作者姓名: Administrator * 创建时间: 2022-07-27 23:35 ******************************/ import com.stu.service.base.utils.JwtUtils; import com.google.gson.JsonObject; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import java.nio.charset.StandardCharsets; import java.util.List; @Component public class AuthGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 获取请求对象 ServerHttpRequest request = exchange.getRequest(); String path = request.getURI().getPath(); // 匹配路由 AntPathMatcher antPathMatcher = new AntPathMatcher(); // 判断路径中如果含有 /api/**/auth/**,则需要鉴权 if (antPathMatcher.match("/api/**/auth/**", path)) { // 获取 token List<String> tokenList = request.getHeaders().get("token"); // 没有 token if (tokenList == null) { ServerHttpResponse response = exchange.getResponse(); // 鉴权失败 return this.out(response); } // token 检验失败 boolean isCheck = JwtUtils.checkJwtToken(tokenList.get(0)); if (!isCheck) { ServerHttpResponse response = exchange.getResponse(); // 鉴权失败 return this.out(response); } } // 放行: 使用过滤器链,将请求继续向下传递 return chain.filter(exchange); } /** * 定义当前过滤器的优先级 * - 值越小, 优先级越高 */ @Override public int getOrder() { return 0; } /** * 使用 webflux 输入请求信息 */ private Mono<Void> out(ServerHttpResponse response) { JsonObject message = new JsonObject(); message.addProperty("success", false); message.addProperty("code", 28004); message.addProperty("data", ""); message.addProperty("message", "鉴权失败"); byte[] bytes = message.toString().getBytes(StandardCharsets.UTF_8); DataBuffer buffer = response.bufferFactory().wrap(bytes); //指定编码,否则在浏览器中会中文乱码 response.getHeaders().add("Content-Type", "application/json;charset=UTF-8"); //输出http响应 return response.writeWith(Mono.just(buffer)); } }
<?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> <modules> <module>service</module> <module>common</module> <module>infrastructure</module> </modules> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.stu</groupId> <artifactId>edu_parent</artifactId> <packaging>pom</packaging> <version>0.0.1-SNAPSHOT</version> <name>edu_parent</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <mybatis-plus.version>3.4.0</mybatis-plus.version> <velocity.version>2.0</velocity.version> <swagger.version>2.9.2</swagger.version> <aliyun.oss.version>3.1.0</aliyun.oss.version> <jodatime.version>2.10.6</jodatime.version> <commons-fileupload.version>1.3.1</commons-fileupload.version> <commons-io.version>2.6</commons-io.version> <commons-lang.version>3.9</commons-lang.version> <httpclient.version>4.5.1</httpclient.version> <jwt.version>0.9.1</jwt.version> <aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version> <aliyun-java-sdk-kms.version>2.10.1</aliyun-java-sdk-kms.version> <aliyun-java-sdk-vod.version>2.15.10</aliyun-java-sdk-vod.version> <aliyun-sdk-vod-upload.version>1.4.11</aliyun-sdk-vod-upload.version> <fastjson.version>1.2.28</fastjson.version> <gson.version>2.8.2</gson.version> <json.version>20170516</json.version> <commons-dbutils.version>1.6</commons-dbutils.version> <canal.client.version>1.1.4</canal.client.version> <docker.image.prefix>zx</docker.image.prefix> <alibaba.easyexcel.version>2.2.6</alibaba.easyexcel.version> <apache.xmlbeans.version>3.1.0</apache.xmlbeans.version> <cloud-alibaba.version>2.2.1.RELEASE</cloud-alibaba.version> <spring-cloud-starter-gateway>2.2.0.RELEASE</spring-cloud-starter-gateway> </properties> <dependencyManagement> <dependencies> <!--Spring Cloud--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR8</version> <type>pom</type> <scope>import</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-dependencies --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!--mybatis-plus 持久层--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>${mybatis-plus.version}</version> </dependency> <!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>${velocity.version}</version> </dependency> <!--swagger--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> </dependency> <!--swagger ui--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger.version}</version> </dependency> <!--aliyunOSS--> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>${aliyun.oss.version}</version> </dependency> <!--日期时间工具--> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>${jodatime.version}</version> </dependency> <!--文件上传--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons-fileupload.version}</version> </dependency> <!--commons-io--> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> </dependency> <!--commons-lang3--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang.version}</version> </dependency> <!--httpclient--> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${httpclient.version}</version> </dependency> <!-- JWT --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>${jwt.version}</version> </dependency> <!--aliyun--> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>${aliyun-java-sdk-core.version}</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-kms</artifactId> <version>${aliyun-java-sdk-kms.version}</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-vod</artifactId> <version>${aliyun-java-sdk-vod.version}</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-sdk-vod-upload</artifactId> <version>${aliyun-sdk-vod-upload.version}</version> </dependency> <!-- json--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>${json.version}</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>${gson.version}</version> </dependency> <dependency> <groupId>commons-dbutils</groupId> <artifactId>commons-dbutils</artifactId> <version>${commons-dbutils.version}</version> </dependency> <dependency> <groupId>com.alibaba.otter</groupId> <artifactId>canal.client</artifactId> <version>${canal.client.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>${alibaba.easyexcel.version}</version> </dependency> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>${apache.xmlbeans.version}</version> </dependency> </dependencies> </dependencyManagement> <!-- <build>--> <!-- <plugins>--> <!-- <plugin>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-maven-plugin</artifactId>--> <!-- </plugin>--> <!-- </plugins>--> <!-- </build>--> </project>