在Java中编码URL查询参数

问题描述 投票:0回答:9

如何在 Java 中对 url 上的查询参数进行编码?我知道,这似乎是一个显而易见且已经被问到的问题。

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

  1. URL 中的空格应该编码为“+”还是“%20”?在 chrome 中,如果我输入“http://google.com/foo=?bar me”,chrome 会将其更改为使用 %20
  2. 进行编码
  3. 将冒号“:”编码为 %3B 是否必要/正确? Chrome 没有。

备注:

  • java.net.URLEncoder.encode
    似乎不起作用,它似乎是为了编码要提交表单的数据。例如,它将空格编码为
    +
    而不是
    %20
    ,并对不必要的冒号进行编码。
  • java.net.URI
    不编码查询参数
java urlencode
9个回答
149
投票

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

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

另一方面,百分比编码(也称为URL编码)使用

%20
对空间进行编码。冒号是保留字符,因此编码后
:
仍然是冒号。


24
投票

不幸的是,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);

16
投票

编辑:

URIUtil
在更新的版本中不再可用,更好的答案在Java - 编码URL或由Sindi先生在此线程中提供。


Apache httpclient 的

URIUtil
确实很有用,尽管有一些 替代品

URIUtil.encodeQuery(url);

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

两者都在正确的上下文中完全有效。不过,如果您确实愿意,可以发出字符串替换。


11
投票

没有必要在查询中将冒号编码为 %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 规范了解更多详细信息。


4
投票

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

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

“:”应该进行编码,因为它是分隔符。即 http://fooftp://bar。事实上,特定浏览器可以在未编码的情况下处理它,但这并不意味着它是正确的。你应该对它们进行编码。

作为良好实践,请务必使用采用字符编码参数的方法。那里通常使用 UTF-8,但您应该明确提供它。

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

3
投票

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

如果你的项目依赖于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


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

我观察到日期时间(时间戳)

URLEncoder.encode(param,"UTF-8")
不起作用。


0
投票

使用

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


-3
投票

如果您只有网址中的空格问题。我使用了下面的代码,它工作正常

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

示例:网址为

www.xyz.com?para=你好先生

那么 muUrl 的输出是

www.xyz.com?para=hello%20先生

© www.soinside.com 2019 - 2024. All rights reserved.