在Spring云网关中,如何根据请求头制作自定义的“动态”路由?

问题描述 投票:0回答:1

我想制作一个自定义路由,如下所示:带有标头“to:221.221.221.221”的请求发送到网关,例如“133.113.113.133”,并且被网关阻止,网关应该检查这一点请求的标头“to:221.221.221.221”,并将该请求发送到“221.221.221.221”。 我应该怎么办?我试图通过编写自己的“动态”路线来解决这个问题,如下所示。 春天: 云: 网关: 路线: - id:自定义路线 uri:http://{主机名}:15412 谓词: - 标头=co,{主机名}

    - id: custom_route
      uri: http://{ hostnameAndPort }
      predicates:
        - Header=co, { hostnameAndPort }

and what's more

@豆子 公共RouteLocator myRoutes(RouteLocatorBuilderrouteLocatorBuilder,HttpServletRequest请求) { String newUri = request.getHeader("newUri"); 返回routeLocatorBuilder.routes() .路线(r-> r.uri(newUri)) 。建造(); }

but still can't work


But anyway, I failed. So what should I do to solve this problem?
I'll appreciate it a lot if anybody can help.


I look for the official doc, and still can't solve this problem.
java routes filter spring-cloud spring-cloud-gateway
1个回答
0
投票

您可以创建自定义路由配置来读取标头值并相应地转发请求。

  • 定义一个过滤器,用于检查请求标头并动态设置 URI(请参阅使用 RouteLocatorBuilder 和自定义过滤器实现的示例代码示例)
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("custom_route", r -> r
                        .predicate(exchange -> hasTargetHeader(exchange, "to"))
                        .filters(f -> f.filter((exchange, chain) -> {
                            String targetUri = exchange.getRequest().getHeaders().getFirst("to");
                            if (targetUri != null) {
                                exchange.getAttributes().put("requestUri", targetUri);
                            }
                            return chain.filter(exchange);
                        }))
                        .uri("lb://default-service")) // Placeholder URI, will be dynamically replaced
                .build();
    }

    private boolean hasTargetHeader(ServerWebExchange exchange, String headerName) {
        return exchange.getRequest().getHeaders().containsKey(headerName);
    }
}
  • 然后实现自定义 GlobalFilter 以根据标头修改传出请求
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class DynamicUriFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String targetUri = exchange.getRequest().getHeaders().getFirst("to");
        if (targetUri != null) {
            exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, URI.create("http://" + targetUri));
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1; // Execute before standard routing
    }
}

希望这有效..

© www.soinside.com 2019 - 2024. All rights reserved.