目录
在《从0到1学SpringCloud——12 gateway 动态配置网关路由规则》一文介绍了通过数据库配置断言信息来实现动态路由的方式,今天介绍通过RouteLocator如何配置路由信息。
官方给出了代码样例:
- import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
- import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;
-
- @Bean
- public RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder){
- return routeBuilder.routes()
- .route("test1", r -> {
- return r.host("*.somehost.org").and().path("/somepath")
- .filters(f -> f.addRequestHeader("header1", "header-value-1"))
- .uri("http://someuri")
- .metadata(RESPONSE_TIMEOUT_ATTR, 200)
- .metadata(CONNECT_TIMEOUT_ATTR, 200);
- })
- .build();
- }
这种方式比上一篇中使用PredicateDefinition要灵活的多,PredicateDefinition对参数类型有所限制,但是使用RouteLocator则灵活的多。
根据官方样例,自定义一个,代码:
- @Configuration
- public class GateWayConfig {
- @Bean
- public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
- // 构建多个路由routes
- RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
-
- routes.route("zhufeng-route-msg",
- r -> r.path("/msg/**").and().method("POST").
- uri("lb://zhufeng-web-msg"));
-
- routes.route("zhufeng-route-user",
- r -> r.path("/user/**").and().method("GET").
- uri("lb://zhufeng-web-user"));
- // 返回所有路由规则
- return routes.build();
- }
- }
先做一个简单的配置:
创建两个微服务zhufeng-web-user、zhufeng-web-msg,启动网关

发送 user 为前缀的GET请求时,自动路由到zhufeng-web-user微服务

改为发送POST请求时,报错:

发送msg为前缀到POST请求时,自动路由到zhufeng-web-msg微服务

发送GET请求时报错:

配置的两个路由规则已经生效,同一个路由多个规则之间通过 and 或者 or 连接。
修改zhufeng-route-msg路由规则,新增过滤器:
routes.route("zhufeng-route-msg", r -> r.path("/json").and().method("POST").filters(f -> f.prefixPath("/msg/")).uri("lb://zhufeng-web-msg"));
当发送 json 为前缀的请求时,自动在 json 前加上 msg 前缀

请求效果与之前的 http://127.0.0.1:9990/msg/json 相同。
- routes.route("zhufeng-route-msg",
- r -> r.readBody(UserInfo.class, requestBody -> true).and().path("/msg/**").
- uri("lb://zhufeng-web-msg"));
在路由信息中,可以指定readBody的格式,可以为JSONObject、XML,设置可以自定义UserInfo对象。在报文体body解析时,根据不同的对象类型,进行不同的解析校验,限于篇幅,下篇展开讲解。
本篇中大部分代码在上一篇中已经提到,代码示例可参考上一篇。