SpringCloud Gateway如何基于URL与请求Method配置不同过滤器
解决方案
你可以直接使用Spring Cloud Gateway内置的两个断言工厂,无需修改原有URL,仅给现有路由追加对应断言即可实现需求:
实现步骤
- 给两个路由分别追加
Method断言,匹配对应HTTP请求方法 - 给GET请求的路由额外追加
Query断言,匹配view=single的请求参数 - 调整路由顺序,匹配条件更严格的路由排在前面,避免被泛匹配路由提前拦截
代码示例(基于你已实现的RouteDefinitionLocator接口)
@Override public Flux<RouteDefinition> getRouteDefinitions() { // 1. 构建POST /v1/orders的路由 RouteDefinition postOrderRoute = new RouteDefinition(); postOrderRoute.setId("post_v1_orders"); postOrderRoute.setUri("lb://你的目标服务名"); // 替换为实际服务路由地址 // 配置断言 List<PredicateDefinition> postPredicates = new ArrayList<>(); // 原有路径断言保留 PredicateDefinition pathPredicate = new PredicateDefinition(); pathPredicate.setName("Path"); pathPredicate.addArg("pattern", "/v1/orders"); postPredicates.add(pathPredicate); // 新增Method断言 匹配POST请求 PredicateDefinition methodPredicate = new PredicateDefinition(); methodPredicate.setName("Method"); methodPredicate.addArg("methods", "POST"); postPredicates.add(methodPredicate); postOrderRoute.setPredicates(postPredicates); // 配置POST接口对应的两个过滤器 List<FilterDefinition> postFilters = new ArrayList<>(); postFilters.add(new FilterDefinition("ValidUser")); postFilters.add(new FilterDefinition("Has Create Permission")); // 替换为你实际的过滤器名称 postOrderRoute.setFilters(postFilters); postOrderRoute.setOrder(0); // 优先级设为最高 // 2. 构建GET /v1/orders?view=single的路由 RouteDefinition getOrderRoute = new RouteDefinition(); getOrderRoute.setId("get_v1_orders_single"); getOrderRoute.setUri("lb://你的目标服务名"); // 替换为实际服务路由地址 // 配置断言 List<PredicateDefinition> getPredicates = new ArrayList<>(); // 原有路径断言保留 PredicateDefinition getPathPredicate = new PredicateDefinition(); getPathPredicate.setName("Path"); getPathPredicate.addArg("pattern", "/v1/orders"); getPredicates.add(getPathPredicate); // 新增Method断言 匹配GET请求 PredicateDefinition getMethodPredicate = new PredicateDefinition(); getMethodPredicate.setName("Method"); getMethodPredicate.addArg("methods", "GET"); getPredicates.add(getMethodPredicate); // 新增Query断言 匹配view参数值为single PredicateDefinition queryPredicate = new PredicateDefinition(); queryPredicate.setName("Query"); queryPredicate.addArg("param", "view"); queryPredicate.addArg("regexp", "single"); getPredicates.add(queryPredicate); getOrderRoute.setPredicates(getPredicates); // 配置GET接口对应的过滤器 List<FilterDefinition> getFilters = new ArrayList<>(); getFilters.add(new FilterDefinition("ValidUser")); getOrderRoute.setFilters(getFilters); getOrderRoute.setOrder(1); // 优先级次于POST路由 // 如果还有其他匹配/v1/orders的泛化路由,order值设为2及以后即可 return Flux.just(postOrderRoute, getOrderRoute); }
注意事项
- 注意修正你代码中拼写错误的
RouteDefincationLocator为正确的RouteDefinitionLocator - 路由的
order值越小优先级越高,必须保证精确匹配的路由排在泛匹配路由前面,否则会出现匹配错误 - 如果你使用
RouteLocatorBuilder流式API配置路由,逻辑完全一致,分别追加method()和query()方法配置断言即可
内容的提问来源于stack exchange,提问作者Alpesh Jikadra
相关产品推荐
相关产品推荐

