org.springframework.boot
spring-boot-starter-parent
2.0.5.RELEASE
org.springframework.cloud
spring-cloud-starter-gateway
2.0.0.RELEASE
org.springframework.cloud
spring-cloud-starter-alibaba-nacos-discovery
0.2.2.RELEASE
SpringCloud gateway基于webflux实现的,不是基于SpringBoot-web,所以应该删除spring-boot-starter-web依赖 server:
port: 80
####服务网关名称
spring:
application:
name: pitch-gateway
cloud:
gateway:
discovery:
locator:
####允许从注册中心获取地址
enabled: true
routes:
###路由id 自定义唯一
- id: pitch
####pitch-member为会员服务的名称
uri: lb://pitch-member/
filters:
- StripPrefix=1
###路由匹配规则 表示当客户端访问http://ip:80/member/**地址时, gateway就会转发到pitch-member会员服务的具体地址
predicates:
- Path=/member/**
nacos:
discovery:
###将网关服务注册到nacos
server-addr: 127.0.0.1:8848
enabled: true
常见路由策略: https://cloud.spring.io/spring-cloud-gateway/reference/html/import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AppGateway {
public static void main( String[] args ) {
SpringApplication.run(AppGateway.class);
}
}
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
* @author xiaobo
* @Description MyFilter
* @createTime 2020-03-30 20:20
*/
@Component
public class MyFilter implements GlobalFilter {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 获取token
String token = exchange.getRequest().getQueryParams().getFirst("token");
// 判断的token是否为空
if (StringUtils.isEmpty(token)) {
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
String msg = "token not is null ";
DataBuffer buffer = response.bufferFactory().wrap(msg.getBytes());
return response.writeWith(Mono.just(buffer));
}
// 直接转发到我们真实服务
return chain.filter(exchange);
}
}
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class CrossOriginFilter implements GlobalFilter {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 允许跨域请求
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, PUT, OPTIONS, DELETE, PATCH");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
return chain.filter(exchange);
}
}
server:
port: 80
####服务网关名称
spring:
application:
name: pitch-gateway
cloud:
gateway:
discovery:
locator:
####允许从注册中心获取地址
enabled: true
nacos:
discovery:
###将网关服务注册到nacos
server-addr: 127.0.0.1:8848
enabled: true
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
import org.springframework.cloud.gateway.filter.FilterDefinition;
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
import java.net.URI;
import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;
/**
* @author xiaobo
* @Description GatewayService
* @createTime 2020-03-30 21:27
*/
@Service
public class GatewayService implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
@Autowired
private RouteDefinitionWriter routeDefinitionWriter;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
// 路由id 转发的注册中的服务 客户端的访问地址
// 表示当客户端访问gateway的url地址时,gateway就是转发到serverName的真实服务中
public String updateRoute(String id, String serverName, String url) {
RouteDefinition definition = new RouteDefinition();
Map predicateParams = new HashMap<>(8);
PredicateDefinition predicate = new PredicateDefinition();
FilterDefinition filterDefinition = new FilterDefinition();
Map filterParams = new HashMap<>(8);
// fromUriString表示以注册中心服务名作为地址
URI uri = UriComponentsBuilder.fromUriString("lb://" + serverName + "/").build().toUri();
// fromHttpUrl表示以http形式转发地址
// URI uri = UriComponentsBuilder.fromHttpUrl("http://www.baidu.com").build().toUri();
// 定义的路由唯一的id
definition.setId(id);
predicate.setName("Path");
//路由转发地址
predicateParams.put("pattern", url);
predicate.setArgs(predicateParams);
// 名称是固定的, 路径去前缀
filterDefinition.setName("StripPrefix");
filterParams.put("_genkey_0", "1");
filterDefinition.setArgs(filterParams);
definition.setPredicates(Arrays.asList(predicate));
definition.setFilters(Arrays.asList(filterDefinition));
definition.setUri(uri);
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
this.publisher.publishEvent(new RefreshRoutesEvent(this));
return "success";
}
}
import com.pitch.service.GatewayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author xiaobo
* @Description UpdateGatewayController
* @createTime 2020-03-30 21:57
*/
@RestController
public class UpdateGatewayController {
@Autowired
private GatewayService gatewayService;
@GetMapping("/update")
public String update(){
// 路由id
String id = "myId";
// 会员服务
String serverName = "pitch-member";
// 转发地址
String url = "/member/**";
// 这里可以改为从数据库获取
gatewayService.updateRoute(id, serverName, url);
return "success";
}
}
这里需要改成从数据库获取