Uri Query替换及处理

背景

最近开发遇到一个这样的需求,需要处理Url的Query。
需求背景是对网页跳转的来源做埋点,例如:某个网页可能有数个入口,需要埋点来区分用户是从哪个入口打开的这个页面。
那么其实我们只需要将来源作为Query传给前端,前端拿到来源后进行埋点即可。假设我们定Query的Key为"source",Value为各个来源。
由于某些原因,网页之前就可能已经包含Key为"source"的Query,那么某些情况我们可能需要替换Query的Value。

需求分解:
对于Key为"source"的Query,如果这个Url中已经有了这个Query,则替换Query的Value;否则将这个Query的Key和Value拼接到Url后面。例如:
我们要拼接的Query的Key为"source", Value为"home_page",那么:

  1. 对于Url:www.xxx.com/xxxPath/xxx.html,处理过后的Url应为:www.xxx.com/xxxPath/xxx.html?source=home_page.
  2. 对于Url:www.xxx.com/xxxPath/xxx.html?source=order_detail,处理过后的Url应为:www.xxx.com/xxxPath/xxx.html?source=home_page.

完成上述需求有两种方案

  1. 直接处理字符串,使用String的Api(String.indexOf(int) && String.repace(char, char)等)进行替换。
  2. 使用Uri这个类进行处理。

本文主要探讨如何使用Uri实现上述需求。

先贴上代码:

/**
 * 替换或追加name为key的query值
 */
private Uri replaceOrAppendUriQueryParameter(Uri uri, String key, String newValue) {
    final Set<String> params = uri.getQueryParameterNames();
    final Uri.Builder newUri = uri.buildUpon();
    if (params.contains(key)) {
        newUri.clearQuery(); // 清除所有query
        for (String param : params) { // 重新添加或替换query
            if (!TextUtils.isEmpty(param)) {
                newUri.appendQueryParameter(param, param.equals(key) ? newValue : uri.getQueryParameter(param));
            }
        }
    } else {
        newUri.appendQueryParameter(key, newValue);
    }
    return newUri.build();
}

对于想深入了解Uri的读者,可以继续往下看。

Uri是一个专门处理Uri的类,很容易想到,如果Uri也能有类似String的replace方法的话,那么事情就变得简单了。

但是事情并没有想象中那么容易,Uri类并没有提供类似replaec的方法。

让我们先来一窥Uri的真容:

public abstract class Uri implements Parcelable, Comparable<Uri> {

    public static final class Builder {

        private String scheme;
        private Part opaquePart;
        private Part authority;
        private PathPart path;
        private Part query;
        private Part fragment;

        // builder methods...
    }

    // other methods...
}

Uri是什么?

对于Uri和URL区别,我一直都不是很清楚,借此机会了解一下。

先说URI

URI是Uniform Resource Identifier的英文缩写,译为:统一资源标志符。

URL

URI是Uniform Resource Locator的英文缩写,译为:统一资源标志符。

posted @ 2021-09-17 14:28  阿Jay  阅读(826)  评论(0)    收藏  举报