如何在Java中将查询参数编码为URL? 我知道,这似乎是一个显而易见且已经提出的问题。
我不确定有两个微妙之处:
网址上的空格应该编码为" +"还是"%20"? 在chrome中,如果我输入" http://google.com/foo=?bar me",则chrome会将其更改为使用%20进行编码
是否有必要/正确将冒号":"编码为%3B? Chrome没有。
笔记:
java.net.URLEncoder.encode似乎不起作用,似乎是为了编码要提交的数据。 例如,它将空格编码为+而不是%20,并编码不必要的冒号。
java.net.URI不对查询参数进行编码
这个问题看起来很有用:stackoverflow.com/questions/444112/
查询部分的结构取决于服务器,尽管大多数人期望applicationx-www-form-urlencoded键/值对。 详情请参阅:lawicalargumentexception.blogspot.com/2009/12/
java.net.URLEncoder.encode(String s, String encoding)也可以提供帮助。它遵循HTML格式编码application/x-www-form-urlencoded。
URLEncoder.encode(query,"UTF-8");
另一方面,百分比编码(也称为URL编码)使用%20编码空间。冒号是保留字符,因此:在编码后仍将保持冒号。
我提到我不认为可以进行url编码,而是对要通过表单提交的数据进行编码。评论?
那是因为URLEncoder符合applicationx-www-form-urlencoded MIME格式(这是有效的HTML表单编码)。我以为那不是您想要的东西。
是的,这是否会使您的答案丧失资格?或者,您是说它的输出仍然有效,只是比必要的严格?
@Alex Black,我刚刚更新了我的评论。我假设您正在寻找符合RFC2396中指定的URI的编码。
顺便说一句,如果您使用的是HttpClient 4,则无需这样做,因为HttpClient会为您执行此操作。
是的,RFC2396看起来像我想要的编码。在我看来,URLEncoder.encode适用于w3.org/TR/html401/interact/forms.html#form-content-type
@Elite:我似乎无法弄清您的意思:)是的,我正在使用HttpClient 4,到目前为止它对我来说还没有做到。您是说其中有一种方法吗?
不,如果您执行HttpGet,则必须进行编码,但是通常,使用HttpParams传递参数,HttpClient 4知道如何对其进行编码。
我最终使用URLEncoder.encode并将" +"替换为"%20"
@Alex Black,您介意解释为什么吗?
因为我向其发送HTTP请求的(第3方)站点之一不会将" +"解码为"",而是会将"%20"解码为""。
我的帖子似乎已经过时,所以我已经更新了。
它将斜杠编码为"%2F",是否不应该将URL斜杠原样保留?
@golimar不,不应该。应该只给它参数值,而不是整个URL。考虑示例http:example.com?url=http:example.com?q=c&sort=name。是否应该编码&sort=name?无法从URL区分价值。这就是为什么首先需要值编码的确切原因。
但实际上,斜杠是querystring参数值中的合法字符。
编辑:URIUtil在更新的版本中不再可用,Java更好的答案-编码URL或Sindi先生在此线程中。
Apache httpclient的URIUtil确实很有用,尽管有一些替代方法
URIUtil.encodeQuery(url);
For example, it encodes space as"+" instead of"%20"
两者在正确的上下文中都是完全有效的。虽然如果您确实喜欢,可以发出字符串替换。
我将不得不同意。使用HttpClient,您会更加快乐。
看起来很有希望,有偶然的联系吗?我在谷歌搜索,但发现了很多。
HttpClient 4.1中似乎没有这种方法吗? hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/
@Alex,嗯,那很烦人,Ive经常使用该例程,但效果很好。一种想法是从3版本中获取源代码,因为他们现在显然不想再维护它了。
很久以前,我从旧的HTTP Commons复制了该类(并对其进行了更改,使其成为单个类),并将其放在要点上:gist.github.com/agentgt/3011049
您打赌这很烦人。当前,有一个URLEncodedUtils.encodeFormFields是私有静态方法。将此方法声明为public是否合理?
URIUtil.encodeWithinQuery是您要使用的编码单个查询参数的东西,这就是原始问题似乎要问的问题。
不幸的是,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);
+是空格的完美有效编码。
@LawrenceDol正确,但有时+可能会被错误解释-请看C#blogs.msdn.microsoft.com/yangxind/2006/11/08/
这个。 我将各种替代方案与Javascripts encodeURIComponent方法的输出进行了比较,这是我尝试的替代方案(带有空格,土耳其语和德语特殊字符的查询)的唯一完全匹配。
尽管这样做不是违法的,但不必在查询中将冒号编码为%3B。
URI = scheme":" hier-part ["?" query ] ["#" fragment ]
query = *( pchar /"/" /"?" )
pchar = unreserved / pct-encoded / sub-delims /":" /"@"
unreserved = ALPHA / DIGIT /"-" /"." /"_" /"~"
pct-encoded ="%" HEXDIG HEXDIG
sub-delims ="!" /"$" /"&" /"'" /"(" /")" /"*" /"+" /"," /";" /"="
似乎还只有百分比编码的空格有效,因为我怀疑空格是ALPHA还是DIGIT
有关更多详细信息,请参见URI规范。
但是,这样做可以更改URI的含义,因为查询字符串的解释取决于服务器。如果生成的是applicationx-www-form-urlencoded查询字符串,则两者都可以。如果要修复用户键入/粘贴的URL,则应保留:。
@tc。您是正确的,如果将冒号用作通用定界符(RFC第12页);但是,如果未将其用作通用定界符,则两种编码应相同解析。
您还必须小心,因为URL并不是URI的真正子集:adamgent.com/post/25161273526/urls-are-not-a-subset-of-uris
内置的Java URLEncoder正在执行预期的操作,您应该使用它。
" +"或"%20"都是URL中空格字符的有效替代。任一个都会起作用。
应该将":"编码,因为它是分隔符。即http:// foo或ftp:// bar。特定浏览器可以在未编码时就可以处理它的事实并不能使其正确。您应该对它们进行编码。
作为一种好的做法,请确保使用采用字符编码参数的方法。 UTF-8通常在此处使用,但是您应该明确提供它。
URLEncoder.encode(yourUrl,"UTF-8");
+仅表示applicationx-www-form-urlencoded中的空格;即使限于HTTP,也不能保证它能正常工作。同样,:在查询字符串中有效,并且不应转换为%3B。服务器可以选择以不同的方式解释它们。
此方法还编码整个URL斜杠和其他字符,例如http:至http%3A%2F%2F的一部分,这是不正确的
@ToKra您不应该对http:部分进行编码。 该方法用于查询参数和编码的表单数据。 但是,如果您希望将另一个网站的URL作为查询参数传递,则您希望对其进行编码,以避免混淆URL解析器。
@tc我对w3.org/TR/html4/interact/forms.html#h-17.13.3.3的阅读是,所有GET表单数据都被编码为applicationx-www-form-urlencoded内容类型。 这是否意味着必须适用于HTTP?
如果您的网址中只有空格问题。我用下面的代码,它工作正常
String url;
URL myUrl = new URL(url.replace("","%20"));
例如:url是
www.xyz.com?para=hello sir
那么muUrl的输出是
www.xyz.com?para=hello%20sir