2011-03-16 97 views
75

如何编码查询参数以在Java中使用url?我知道,这似乎是一个显而易见的问题。使用Java编码URL查询参数

有两个微妙之处我不知道的:

  1. 如果空间上的网址为“+”或“%20”编码?在Chrome浏览器中,如果我输入“http://google.com/foo=?bar me”,Chrome会将其更改为使用%编码20
  2. 是否需要/正确地将冒号“:”编码为%3B? Chrome没有。

注:

  • java.net.URLEncoder.encode似乎不工作,它似乎是要提交表单数据编码。例如,它将空间编码为+而不是%20,并对不需要的冒号进行编码。
  • java.net.URI不编码查询参数
+0

这个问题看起来有用:http://stackoverflow.com/questions/444112/how-do-i-编码-URI - 对参数值 – 2011-03-16 19:14:43

+2

查询部分的结构依赖于服务器,尽管大多数人期望'application/x-www-form-urlencoded'键/值对。在这里看到更多:http://illegalargumentexception.blogspot.com/2009/12/java-safe-character-handling-and-url.html – McDowell 2011-03-16 20:18:00

回答

88

java.net.URLEncoder.encode(String s, String encoding)也可以提供帮助。它遵循HTML表单编码application/x-www-form-urlencoded

URLEncoder.encode(query, "UTF-8"); 

在另一方面,Percent-encoding(也称为URL encoding)与%20编码空间。冒号是一个保留字符,因此编码后:仍然是冒号。

+2

我提到,我没有想到,URL编码,而是它编码的数据通过表单提交。注释? – 2011-03-16 18:50:06

+0

这是因为URLEncoder符合application/x-www-form-urlencoded的MIME格式(这是一种有效的HTML表单编码)。我假设这不是你想要的。 – 2011-03-16 18:54:10

+0

对,那么这不会使你的答案不合格?或者,你是说它的输出仍然有效,只是比必要更严格? – 2011-03-16 18:55:03

14

编辑:URIUtil不再在最近的版本,更好的答案在Java - encode URL或辛迪先生在这个线程。


的Apache的HttpClient URIUtil是真正有用的,虽然有一些alternatives

URIUtil.encodeQuery(url); 

例如,它编码空间为 “+”,而不是 “%20”

两者都是perfectly valid in the right context。虽然如果你真的喜欢,你可以发出一个字符串替换。

+0

我不得不同意。使用HttpClient,你会更快乐。 – DaShaun 2011-03-16 18:44:35

+0

这看起来很有希望,偶然得到了一个链接?我使用谷歌搜索,但发现很多。 – 2011-03-16 18:44:35

+0

这个方法似乎并不存在于HttpClient 4.1中? http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/client/utils/URIUtils.html – 2011-03-16 18:49:01

7

在查询中不需要将冒号作为%3B进行编码,尽管这样做不是非法的。

URI   = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 
query  = *(pchar/"/"/"?") 
pchar   = unreserved/pct-encoded/sub-delims/":"/"@" 
unreserved = ALPHA/DIGIT/"-"/"."/"_"/"~" 
pct-encoded = "%" HEXDIG HEXDIG 
sub-delims = "!"/"$"/"&"/"'"/"("/")"/"*"/"+"/","/";"/"=" 

这也似乎只有百分之编码的空间是有效的,因为我怀疑,空间是一个字母或一个数字

外观the URI specification了解更多详情。

+0

但是这样做可以改变URI的含义,因为查询字符串的解释取决于服务器。如果你正在生成一个'application/x-www-form-urlencoded'查询字符串,那么就好。如果您正在修改用户键入/粘贴的URL,则应单独保留':'。 – 2013-03-26 18:44:46

+0

@tc。如果冒号被用作通用分隔符(RFC第12页),那么你是对的;然而,如果它没有被用作一个普通的分隔符,那么这两种编码应该以相同的方式解决。 – 2013-03-27 21:24:34

+0

你也必须小心,因为URL并不是URI的子集:http://adamgent.com/post/25161273526/urls-are-not-a-subset-of-uris – 2013-04-25 22:51:04

3

内置的Java URLEncoder正在做它应该做的,你应该使用它。

“+”或“%20”是均为有效替换URL中的空格字符。任何一个都可以工作。

一个“:”应该被编码,因为它是一个分隔符。即http://fooftp://bar。事实上,一个特定的浏览器可以处理它,当它没有编码并不能使它正确。你应该编码它们。

作为一个良好的做法,一定要使用带有字符编码参数的方法。 UTF-8通常在那里使用,但您应该明确提供它。

URLEncoder.encode(yourUrl, "UTF-8"); 
+4

'+'只是一个表示'application/x-www-form-urlencoded'中的空间即使限于HTTP,也不保证能够正常工作。同样,':'在查询字符串中有效*和*不应该转换为'%3B';服务器可以选择以不同的方式解释它们。 – 2013-03-26 18:38:49

+1

此方法也编码整个网址斜线和其他字符,例如'http://'到'http%3A%2F%2F'这是不正确的部分 – 2015-05-22 10:47:13

+0

@ToKra你不应该编码'http:// '部分。该方法用于查询参数和编码形式的数据。但是,如果您想将另一个网站的URL作为查询参数传递,那么您需要对其进行编码以避免混淆URL解析器。 – beldaz 2016-07-15 10:00:36

7

不幸的是,URLEncoder.encode()不产生编码有效百分比(如在http://tools.ietf.org/html/rfc3986#section-2.1指定)。

URLEncoder.encode()编码一切都很好,除了空间编码为“+”。我能找到的所有Java URI编码器都只公开方法来对查询,片段,路径部分等进行编码 - 但不公开“原始”编码。这是不幸的,因为片段和查询被允许将空间编码为+,所以我们不想使用它们。路径编码正确,但首先是“标准化”,因此我们不能将其用于“通用”编码。

我可以拿出最好的解决办法:

return URLEncoder.encode(raw, "UTF-8").replaceAll("\\+", "%20"); 

如果replaceAll()是你太慢了,我想另一种方法是推出自己的编码器...

编辑:我有这个代码在这里先不编码, “&”, “=” 正常 “?”:

//don't use - doesn't properly encode "?", "&", "=" 
new URI(null, null, null, raw, null).toString().substring(1); 
+0

'+'是一个完全有效的空间编码。 – 2015-12-15 23:00:39

+0

@ LawrenceDol这是真的,但有时'+'可能会被错误地解释 - 请看看C#https://blogs.msdn.microsoft.com/yangxind/2006/11/08/dont-use-net-system-uri- unescapedatastring-in-url-decoding/ – Lu55 2016-04-14 08:42:05

+0

这个。我根据Javascript的'encodeURIComponent'方法输出比较了各种替代方法,这是我尝试过的(与空格,土耳其和德国特殊字符查询)唯一完全匹配。 – 2017-11-27 10:43:37