用 Java 编码 URL 查询参数

如何在 Java 中编码查询参数来访问 URL?我知道,这似乎是一个显而易见而且已经问过的问题。

有两个微妙之处我不确定:

  1. Should spaces be encoded on the url as "+" or as "%20"? In chrome if I type in "http://google.com/foo=?bar me" chrome changes it to be encoded with %20
  2. 是否有必要/正确地将冒号“ :”编码为% 3B。

备注:

  • java.net.URLEncoder.encode似乎没有工作,它似乎是为编码数据的形式提交。例如,它将空间编码为 +而不是 %20,并将不必要的冒号编码。
  • java.net.URI不对查询参数进行编码
233836 次浏览

编辑: URIUtil不再提供更新的版本,更好的答案在 Java 编码 URL或由辛迪先生在这个线程。


Apache httpclient 的 URIUtil非常有用,尽管有一些替代方案

URIUtil.encodeQuery(url);

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

两者都是 在正确的环境下是完全有效的。尽管如果你真的喜欢,你可以发出字符串替换。

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

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

另一方面,百分号编码(也称为 URL 编码)用 %20对空间进行编码。冒号是一个保留字符,所以 :在编码之后仍然是冒号。

不需要在查询中将冒号编码为% 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 规范

内置的 JavaURLEncoder 正在做它应该做的事情,你应该使用它。

“ +”或“% 20”是 URL 中空格字符的 都有有效替代品。两者都可以。

应该进行编码,因为它是一个分隔符。即 http://fooFtp://bar。一个特定的浏览器可以在没有编码的情况下处理它,这并不能使它正确。你应该把它们编码。

作为一个好的实践,一定要使用带有字符编码参数的方法。UTF-8通常在这里使用,但是您应该显式地提供它。

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

遗憾的是,URLEncoder.encode ()不能产生有效的百分号编码(如在 RFC 3986中指定的)。

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);

如果你只有空间问题的网址。我已经使用下面的代码,它的工作很好

String url;
URL myUrl = new URL(url.replace(" ","%20"));

例如: url 是

www.xyz.com?para=hello sir

那么 muUrl 的输出是

你好,先生

String param="2019-07-18 19:29:37";
param="%27"+param.trim().replace(" ", "%20")+"%27";

我观察日期时间(时间戳)的情况 URLEncoder.encode(param,"UTF-8") does not work.

我只是想增加另一种方法来解决这个问题。

如果你的项目依赖于弹簧网络,你可以使用他们的工具。

import org.springframework.web.util.UriUtils


import java.nio.charset.StandardCharsets


UriUtils.encode('vip:104534049:5', StandardCharsets.UTF_8)

产出:

vip%3A104534049%3A5


当使用 URLEncoder.encode时,空白字符“”将转换为 + 符号。这与 JavaScript 等其他编程语言相反,后者将空格字符编码为% 20。但是它是完全有效的,因为查询字符串参数中的空格是用 + 表示的,而不是% 20。% 20通常用于表示 URI 本身中的空格(前面的 URL 部分?).