spring cloud gateway支持restful调用

pull/1/head
tanghc 5 years ago
parent 2f4c46dc16
commit fe0d348b41
  1. 2
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/bean/SopConstants.java
  2. 9
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/filter/LoadBalancerClientExtFilter.java
  3. 22
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/GatewayRouteRepository.java
  4. 18
      sop-common/sop-gateway-common/src/main/java/com/gitee/sop/gatewaycommon/gateway/route/NameVersionRoutePredicateFactory.java
  5. 52
      sop-gateway/src/main/java/com/gitee/sop/gateway/controller/RestWebFlux.java

@ -20,6 +20,8 @@ public class SopConstants {
public static final String REDIRECT_VERSION_KEY = "r-version";
public static final String REDIRECT_PATH_KEY = "r-path";
/**
* 在拦截器中调用获取参数
* String cachedBody = (String)exchange.getAttribute(SopConstants.CACHE_REQUEST_BODY_OBJECT_KEY);

@ -1,5 +1,6 @@
package com.gitee.sop.gatewaycommon.gateway.filter;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.util.RouteUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
@ -33,7 +34,7 @@ public class LoadBalancerClientExtFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
String path = this.findPath(route);
String path = this.findPath(exchange, route);
if (StringUtils.hasLength(path)) {
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(url);
@ -44,7 +45,11 @@ public class LoadBalancerClientExtFilter implements GlobalFilter, Ordered {
return chain.filter(exchange);
}
protected String findPath(Route route) {
protected String findPath(ServerWebExchange exchange, Route route) {
String path = exchange.getAttribute(SopConstants.REDIRECT_PATH_KEY);
if (path != null) {
return path;
}
URI routeUri = route.getUri();
String uriStr = routeUri.toString();
return RouteUtil.findPath(uriStr);

@ -5,15 +5,13 @@ import com.gitee.sop.gatewaycommon.bean.TargetRoute;
import com.gitee.sop.gatewaycommon.manager.RouteRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.event.PredicateArgsEvent;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@ -29,6 +27,8 @@ import static java.util.Collections.synchronizedMap;
@Slf4j
public class GatewayRouteRepository implements RouteDefinitionRepository, RouteRepository<GatewayTargetRoute> {
private PathMatcher pathMatcher = new AntPathMatcher();
private final Map<String, GatewayTargetRoute> routes = synchronizedMap(new LinkedHashMap<>());
@Override
@ -57,8 +57,20 @@ public class GatewayRouteRepository implements RouteDefinitionRepository, RouteR
if (id == null) {
return null;
}
return routes.get(id);
GatewayTargetRoute gatewayTargetRoute = routes.get(id);
if (gatewayTargetRoute != null) {
return gatewayTargetRoute;
}
for (Map.Entry<String, GatewayTargetRoute> entry : routes.entrySet()) {
// /food/get/?id?
String pattern = entry.getKey();
if (StringUtils.containsAny(pattern, "{") && this.pathMatcher.match(pattern, id)) {
return entry.getValue();
}
}
return null;
}
@Override
public Collection<GatewayTargetRoute> getAll() {

@ -1,10 +1,13 @@
package com.gitee.sop.gatewaycommon.gateway.route;
import com.gitee.sop.gatewaycommon.bean.SopConstants;
import com.gitee.sop.gatewaycommon.gateway.ServerWebExchangeUtil;
import com.gitee.sop.gatewaycommon.param.ParamNames;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
@ -28,6 +31,8 @@ public class NameVersionRoutePredicateFactory extends AbstractRoutePredicateFact
private static final String PARAM_KEY = "param";
private static final String REGEXP_KEY = "regexp";
private PathMatcher pathMatcher = new AntPathMatcher();
public NameVersionRoutePredicateFactory() {
super(Config.class);
}
@ -57,7 +62,18 @@ public class NameVersionRoutePredicateFactory extends AbstractRoutePredicateFact
if (name == null || version == null) {
return false;
}
return (name.toString() + version).equals(nameVersion);
String key = name.toString() + version.toString();
// 如果是通配符
if (nameVersion.contains("{")) {
boolean match = pathMatcher.match(nameVersion, key);
if (match) {
Map<String, Object> attributes = exchange.getAttributes();
attributes.put(SopConstants.REDIRECT_PATH_KEY, key);
}
return match;
} else {
return key.equals(nameVersion);
}
};
}

@ -0,0 +1,52 @@
package com.gitee.sop.gateway.controller;
import com.gitee.sop.gatewaycommon.param.ParamNames;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import java.net.URI;
/**
* @author tanghc
*/
@Configuration
public class RestWebFlux {
@Value("${sop.restful.path:/rest}")
private String restPath;
/**
* 307 Temporary Redirect临时重定向:
* <p>
* 在这种情况下请求应该与另一个URI重复但后续的请求应仍使用原始的URI
* 与302相反当重新发出原始请求时不允许更改请求方法 例如应该使用另一个POST请求来重复POST请求
* <p>
* 308 Permanent Redirect 永久重定向:
* <p>
* 请求和所有将来的请求应该使用另一个URI重复
* 307和308重复302和301的行为但不允许HTTP方法更改 例如将表单提交给永久重定向的资源可能会顺利进行
* <p>
* https://www.cnblogs.com/wuguanglin/p/redirect.html
*
* @return
*/
@Bean
RouterFunction<ServerResponse> routerFunction() {
return RouterFunctions.route(RequestPredicates.GET(restPath + "/**"), (serverRequest) -> {
String url = serverRequest.path();
int index = url.indexOf(restPath);
// 取/rest的后面部分
String path = url.substring(index + restPath.length());
String query = ParamNames.API_NAME + "=" + path + "&" + ParamNames.VERSION_NAME + "=";
return ServerResponse
.temporaryRedirect(URI.create("/?" + query))
.build();
});
}
}
Loading…
Cancel
Save