专栏首页码匠的流水账聊聊spring cloud gateway的PrefixPath及StripPrefix功能

聊聊spring cloud gateway的PrefixPath及StripPrefix功能

本文主要研究一下spring cloud gateway的PrefixPath及StripPrefix功能

PrefixPathGatewayFilterFactory

spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/filter/factory/PrefixPathGatewayFilterFactory.java

public class PrefixPathGatewayFilterFactory extends AbstractGatewayFilterFactory<PrefixPathGatewayFilterFactory.Config> {

    private static final Log log = LogFactory.getLog(PrefixPathGatewayFilterFactory.class);

    public static final String PREFIX_KEY = "prefix";

    public PrefixPathGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(PREFIX_KEY);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {

            boolean alreadyPrefixed = exchange.getAttributeOrDefault(GATEWAY_ALREADY_PREFIXED_ATTR, false);
            if (alreadyPrefixed) {
                return chain.filter(exchange);
            }
            exchange.getAttributes().put(GATEWAY_ALREADY_PREFIXED_ATTR, true);

            ServerHttpRequest req = exchange.getRequest();
            addOriginalRequestUrl(exchange, req.getURI());
            String newPath = config.prefix + req.getURI().getRawPath();

            ServerHttpRequest request = req.mutate()
                    .path(newPath)
                    .build();

            exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());

            if (log.isTraceEnabled()) {
                log.trace("Prefixed URI with: "+config.prefix+" -> "+request.getURI());
            }

            return chain.filter(exchange.mutate().request(request).build());
        };
    }

    public static class Config {
        private String prefix;

        public String getPrefix() {
            return prefix;
        }

        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }
    }
}

可以看到这里使用config的prefix构造newPath,然后构造新的ServerHttpRequest

实例

spring:
  cloud:
    gateway:
      routes:
      - id: prefixpath_route
        uri: http://example.org
        filters:
        - PrefixPath=/mypath

比如:请求/hello,最后转发到目标服务的路径变为/mypath/hello

StripPrefixGatewayFilterFactory

spring-cloud-gateway-core-2.0.0.RC2-sources.jar!/org/springframework/cloud/gateway/filter/factory/StripPrefixGatewayFilterFactory.java

/**
 * This filter removes the first part of the path, known as the prefix, from the request
 * before sending it downstream
 * @author Ryan Baxter
 */
public class StripPrefixGatewayFilterFactory extends AbstractGatewayFilterFactory<StripPrefixGatewayFilterFactory.Config> {

    public static final String PARTS_KEY = "parts";

    public StripPrefixGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(PARTS_KEY);
    }

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) ->  {
            ServerHttpRequest request = exchange.getRequest();
            addOriginalRequestUrl(exchange, request.getURI());
            String path = request.getURI().getRawPath();
            String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(path, "/"))
                    .skip(config.parts).collect(Collectors.joining("/"));
            ServerHttpRequest newRequest = request.mutate()
                    .path(newPath)
                    .build();

            exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());

            return chain.filter(exchange.mutate().request(newRequest).build());
        };
    }

    public static class Config {
        private int parts;

        public int getParts() {
            return parts;
        }

        public void setParts(int parts) {
            this.parts = parts;
        }
    }
}

可以看到这里的parts指定要去除的前缀的个数,然后使用stream的skip来去除掉相应前缀,然后得到newPath,构造newRequest

实例

spring:
  cloud:
    gateway:
      routes:
      - id: nameRoot
        uri: http://nameservice
        predicates:
        - Path=/name/**
        filters:
        - StripPrefix=2

比如,请求/name/bar/foo,去除掉前面两个前缀之后,最后转发到目标服务的路径为/foo

小结

PrefixPathGatewayFilterFactory及StripPrefixGatewayFilterFactory是一对针对请求url前缀进行处理的filter工厂,前者添加prefix,后者去除prefix。

doc

  • 112.5 PrefixPath GatewayFilter Factory

本文分享自微信公众号 - 码匠的流水账(geek_luandun),作者:码匠乱炖

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-06-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • leetcode之二进制求和

    这里对两个字符串从后开始遍历,然后进行累加,对2取余数添加到结果集,然后对2取模,继续循环,最后将结果反转一下,最后再判断一下sum是否大于0,大于0的话,再补...

    codecraft
  • 聊聊consul的NewService

    consul-api-1.4.1-sources.jar!/com/ecwid/consul/v1/agent/model/NewService.java

    codecraft
  • leetcode之二进制求和

    这里对两个字符串从后开始遍历,然后进行累加,对2取余数添加到结果集,然后对2取模,继续循环,最后将结果反转一下,最后再判断一下sum是否大于0,大于0的话,再补...

    codecraft
  • 单词接龙

    给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。转换需遵...

    你的益达
  • Struts2学习---简单的数据校验、访问Web元素 1.简单的数据校验访问Web元素

    1.简单的数据校验 在action里面我们已经给出了一个数据校验: public String execute() { if(user.getU...

    MindMrWang
  • Android-performTraversals

    该方法是在ViewRootImpl.java文件中,一旦触发该操作,就会从decorView开始进行measure,Layout,draw了。 在schedu...

    None_Ling
  • 浅谈JAVA设计模式之——责任链模式(COR)

    使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链, 并沿着这条链传递该请求,直到有一个对象处理它为止。这一模式的想法...

    冰河
  • linux内核调试技巧之一 dump_stack【转】

    遇到uvc_probe_video这么一个函数,不知道它最终是被谁调用到的,根据linux设备模型,初步推测,probe应该是设备适配驱动时总线轮训到的。

    233333
  • 宋宝华:Linux文件读写(BIO)波澜壮阔的一生

    网上关于BIO和块设备读写流程的文章何止千万,但是能够让你彻底读懂读明白的文章实在难找,可以说是越读越糊涂!

    Linux阅码场
  • PNAS:青少年大脑网络的结构-功能耦合关系的发育状况

    《本文同步发布于“脑之说”微信公众号,欢迎搜索关注~~》 一、引言     结构-功能之间的关系一直是神经科学领域比较关注的热点问题。青少年脑部白质纤维...

    悦影科技

扫码关注云+社区

领取腾讯云代金券