Android中的URL编码


335

您如何在Android中编码URL

我以为是这样的:

final String encodedURL = URLEncoder.encode(urlAsString, "UTF-8");
URL url = new URL(encodedURL);

如果执行上述操作,则将http://in urlAsString替换为http%3A%2F%2Fin encodedURL,然后java.net.MalformedURLException在使用URL时得到 。

Answers:


630

您无需对整个URL进行编码,而仅对其中一部分来自“不可靠的来源”进行编码。

String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;

另外,您可以使用不引发检查异常的DroidParts的Strings.urlEncode(String str)

或使用类似

String uri = Uri.parse("http://...")
                .buildUpon()
                .appendQueryParameter("key", "val")
                .build().toString();

1
如果整个网址不可靠怎么办?我应该对除协议之外的所有内容进行编码吗?我有点希望这样做很方便。
hpique 2010年

5
然后,这只是一个损坏的网址。这样做的目的是防止查询部分破坏URL。
扬琴科

5
@hgpc-看一下RFC3986的第3部分(tools.ietf.org/html/rfc3986#section-3)。它告诉您如何编码URI的各个部分。不幸的是,URI的每个部分(主机,路径,查询等)都有稍微不同的编码规则。
D.Shawley

2
这样做很好,因为您只处理URL的特定部分,并且知道如何构造或重构URL。有关可以处理任何url字符串的更通用方法,请参见下面的答案。
Craig B

8
为什么使用此方法会收到弃用警告?使用Uri.encode(query);来代替。
prasanthv 2014年

166

我将在这里添加一个建议。您可以这样做,避免了必须获取任何外部库的情况。

试试看:

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

您可以看到,在此特定的URL中,我需要对那些空格进行编码,以便可以将其用于请求。

这利用了Android类中提供的几个功能。首先,URL类可以将url分解为其适当的组成部分,因此您无需进行任何字符串搜索/替换工作。其次,当您通过组件而不是从单个字符串构造URI时,此方法利用了URI类功能,可以正确地转义组件。

这种方法的优点在于,您可以接受任何有效的url字符串并使它工作,而无需您自己对此有任何特殊的了解。


19
这应该是正确的答案。这是执行此操作的正式且清晰的方法
Asanka Senavirathna

3
在将urlStr发送到URL构造函数之前对urlStr进行解码也是一个好主意。URLDecoder.decode(urlStr)
雅各布·埃里克森

1
感谢您的帖子:)但是我面临一个问题。如果url已被部分编码,则表示已对已编码的部分进行编码。我该怎么办?例如:dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/…%20被编码为%2520
疯抢

2
@berserk如果已编码,请不要对其进行编码。您不应该进入部分编码的状态,或者不确定是否已编码。
2014年

3
此方法不会将ğ等字符编码为%C4%9F。接受一个编码!
亚历山大·普罗科菲耶夫

74

对于android,我将使用String android.net.Uri.encode(String s)

使用UTF-8方案将给定字符串中的字符编码为'%'转义的八位字节。保留字母(“ AZ”,“ az”),数字(“ 0-9”)和未保留的字符(“ _- !.〜'()*”)完整无缺。编码所有其他字符。

例/

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);

2
不幸的是Uri.encode("a=1&b=1")产生了a%3D1%26b%3D1但是期望了a=1&b=1
loentar

14
@loentar这是预期的结果。如果用户输入a=1&b=1为查询,则您要查询准确。
Anubian Noob 2015年

与URLEncoder.encode(StringHere,“ UTF-8”)的
区别是什么

@stuckedoverflow一方面,与URLEncoder.encode(str,“ UTF-8”)不同,Uri.encode(str)不会引发已检查的异常
deekshith

50

你也可以用这个

private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
String urlEncoded = Uri.encode(path, ALLOWED_URI_CHARS);

这是最简单的方法


1
这不是最好的解决方案,但这绝对是一个不错的快速解决方案……谢谢
Sebastian Breit 2014年

4
当整个URL不可靠时,这是最快的解决方案。谢谢!
user1032613 2014年

您确定应该允许%吗?不应该编码吗?
2015年

1
如何对该URL进行编码以使其可以共享,然后用户可以打开链接并查看页面: yazd20.com//News/2015/11/استند-آب-كمدي-حسن-ريوندي-در-يزد。html
艾哈迈德·埃布拉希米

3
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

1

您可以使用以下方法

public static String parseUrl(String surl) throws Exception
{
    URL u = new URL(surl);
    return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}

要么

public String parseURL(String url, Map<String, String> params)
{
    Builder builder = Uri.parse(url).buildUpon();
    for (String key : params.keySet())
    {
        builder.appendQueryParameter(key, params.get(key));
    }
    return builder.build().toString();
}

第二个比第一个好。


0

查找阿拉伯字符,并将其替换为UTF-8编码。像这样的东西:

for (int i = 0; i < urlAsString.length(); i++) {
    if (urlAsString.charAt(i) > 255) {
        urlAsString = urlAsString.substring(0, i) + URLEncoder.encode(urlAsString.charAt(i)+"", "UTF-8") + urlAsString.substring(i+1);
    }
}
encodedURL = urlAsString;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.