如何在 Java 中对 url 上的查询参数进行编码?我知道,这似乎是一个显而易见且已经被问到的问题。
有两个微妙之处我不确定:
备注:
java.net.URLEncoder.encode
似乎不起作用,它似乎是为了编码要提交表单的数据。例如,它将空格编码为 +
而不是 %20
,并对不必要的冒号进行编码。java.net.URI
不编码查询参数java.net.URLEncoder.encode(String s, String encoding)
也可以提供帮助。它遵循 HTML 表单编码application/x-www-form-urlencoded
。
URLEncoder.encode(query, "UTF-8");
%20
对空间进行编码。冒号是保留字符,因此编码后:
仍然是冒号。
不幸的是,URLEncoder.encode() 不会产生有效的百分比编码(如RFC 3986中指定)。
URLEncoder.encode() 可以很好地对所有内容进行编码,除了空格被编码为“+”。我能找到的所有 Java URI 编码器都只公开公共方法来编码查询、片段、路径部分等,但不公开“原始”编码。不幸的是,因为片段和查询允许将空格编码为 +,所以我们不想使用它们。路径已正确编码,但首先“标准化”,因此我们也不能将其用于“通用”编码。
我能想到的最佳解决方案:
return URLEncoder.encode(raw, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
如果
replaceAll()
对你来说太慢,我想另一种选择是滚动你自己的编码器......
编辑:我首先在这里有这段代码,它没有正确编码“?”,“&”,“=”:
//don't use - doesn't properly encode "?", "&", "="
new URI(null, null, null, raw, null).toString().substring(1);
编辑:
URIUtil
在更新的版本中不再可用,更好的答案在Java - 编码URL或由Sindi先生在此线程中提供。
URIUtil
确实很有用,尽管有一些 替代品
URIUtil.encodeQuery(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 = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
似乎只有百分比编码的空格才是有效的,因为我怀疑空格是字母还是数字
请参阅 URI 规范了解更多详细信息。
内置的 Java URLEncoder 正在做它应该做的事情,你应该使用它。
“+”或“%20”都是 URL 中空格字符的有效替换。任何一个都可以。
“:”应该进行编码,因为它是分隔符。即 http://foo 或 ftp://bar。事实上,特定浏览器可以在未编码的情况下处理它,但这并不意味着它是正确的。你应该对它们进行编码。
作为良好实践,请务必使用采用字符编码参数的方法。那里通常使用 UTF-8,但您应该明确提供它。
URLEncoder.encode(yourUrl, "UTF-8");
我只是想添加另一种方法来解决这个问题。
如果你的项目依赖于spring web,你可以使用他们的utils。
import org.springframework.web.util.UriUtils
import java.nio.charset.StandardCharsets
UriUtils.encode('vip:104534049:5', StandardCharsets.UTF_8)
输出:
vip%3A104534049%3A5
String param="2019-07-18 19:29:37";
param="%27"+param.trim().replace(" ", "%20")+"%27";
我观察到日期时间(时间戳)
URLEncoder.encode(param,"UTF-8")
不起作用。
使用
URLEncoder.encode
时,空白字符“ ”会转换为 + 号。这与 JavaScript 等其他编程语言相反,JavaScript 将空格字符编码为 %20。但它是完全有效的,因为查询字符串参数中的空格由 + 表示,而不是 %20。 %20 通常用于表示 URI 本身中的空格(前面的 URL 部分?)。
如果您只有网址中的空格问题。我使用了下面的代码,它工作正常
String url;
URL myUrl = new URL(url.replace(" ","%20"));
示例:网址为
www.xyz.com?para=你好先生
那么 muUrl 的输出是
www.xyz.com?para=hello%20先生