背景:第三方公司 请求本公司入参和出参一样的同一个接口,根据业务类型不一样需要不同业务微服务处理 ,和第三方公司协商在请求头中加入业务类型方便我公司在网关成分发请求。
1:在spring cloud gateway yml 中加入路由 重点是 - id: hello_route
server:
port: 7101
servlet:
context-path: /
spring:
application:
name: spring-cloud-gateway
cloud:
gateway:
discovery:
locator:
enabled: true #开启Eureka服务发现
lower-case-service-id: true
routes:
- id: baidu_route
uri: http://www.baidu.com
predicates:
- Path=/baidu/**
filters:
- StripPrefix=1
- id: hello_route
uri: http://localhost:7002
predicates:
- Path=/hello
filters:
- CustomRewriteRouteFilter=true # ##自定义过滤器必须有
eureka:
client:
service-url:
defaultZone: ${EUREKA_URI:http://localhost:8761/eureka}
instance:
prefer-ip-address: true
logging:
level:
org.springframework.cloud.gateway: debug
2:过滤器实现
package tigee.filter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.util.List;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
@Component
public class CustomRewriteRouteFilter extends AbstractGatewayFilterFactory {
private static final Log log = LogFactory.getLog(CustomRewriteRouteFilter.class);
@Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
//获取url地址
ServerHttpRequest request = exchange.getRequest();
String rawPath = request.getURI().getRawPath();
//请求头
HttpHeaders headers = request.getHeaders();
//请求方法
HttpMethod method = request.getMethod();
//请求参数
MultiValueMap < String, String > queryParams = request.getQueryParams();
List<String> serveqp = queryParams.get("serve");
log.info("serveqp--->:"+serveqp);
List<String> servehd = headers.get("serve");
String serve = "";
if(!CollectionUtils.isEmpty(serveqp)){
serve =serveqp.get(0);
}else if(!CollectionUtils.isEmpty(servehd)){
serve =servehd.get(0);
}
log.info("serve--->:"+serve);
URI uri = UriComponentsBuilder.fromUriString("lb://"+serve).queryParams(queryParams).build().toUri();
//替换新的url地址
ServerHttpRequest serverHttpRequest = request.mutate().uri(uri).path(request.getPath().value()).method(method).headers(
httpHeaders -> httpHeaders=headers).build();
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
//从新设置Route地址
Route newRoute =
Route.async().asyncPredicate(route.getPredicate()).filters(route.getFilters()).id(route.getId())
.order(route.getOrder()).uri(uri).build();
exchange.getAttributes().put(GATEWAY_ROUTE_ATTR,newRoute);
return chain.filter(exchange.mutate().request(serverHttpRequest).build());
};
}
}
3:user-service 和 order-service 创建hellocontroller
@RestController
public class HelloController{
@Value("${server.port}")
private int port;
@Value("${spring.application.name}")
private String serve;
@RequestMapping("hello")
public String hello(String name){
return "你好:"+serve+":"+port+":"+name;
}
}
4:启动服务
5:验证
postman 请求 http://localhost:7101/hello?name=name2
header中加入 serve = user-service 或者 order-service