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",那么:
- 对于Url:www.xxx.com/xxxPath/xxx.html,处理过后的Url应为:www.xxx.com/xxxPath/xxx.html?source=home_page.
- 对于Url:www.xxx.com/xxxPath/xxx.html?source=order_detail,处理过后的Url应为:www.xxx.com/xxxPath/xxx.html?source=home_page.
完成上述需求有两种方案:
- 直接处理字符串,使用String的Api(
String.indexOf(int)&&String.repace(char, char)等)进行替换。 - 使用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的英文缩写,译为:统一资源标志符。

浙公网安备 33010602011771号