编码URL查询参数

14

我该如何对URL查询参数值进行编码? 我需要将空格替换为%20,同时还要处理重音符号、非ASCII字符等。

我尝试使用URLEncoder,但它也会对/字符进行编码,如果我将使用URLEncoder编码后的字符串传递给URL构造函数,我会得到一个MalformedURLException(没有协议)。


4
请提供一些字符串示例及相关的代码。 - Lukas Knuth
不同的编码规则将适用于URI的不同部分。正如Lukas所建议的那样,请提供您开始使用的信息和您想要达到的目标的示例。 - McDowell
2个回答

35

URLEncoder的名称非常具有误导性。根据Javadocs,它用于使用MIME类型application/x-www-form-urlencoded编码表单参数。

尽管如此,它也可以用于编码例如查询参数等。例如,如果一个参数看起来像&/?#,它的编码等效形式可以被用作:

String url = "http://host.com/?key=" + URLEncoder.encode("&/?#");

除非你有特殊需求,否则建议使用new URI(..).toURL。在URL javadocs中也有这个建议,此方法会按照RFC2396对URI进行编码。

管理URL的编码和解码的推荐方法是使用URI

以下为示例:

new URI("http", "host.com", "/path/", "key=| ?/#ä", "fragment").toURL();

生成的结果为 http://host.com/path/?key=%7C%20?/%23ä#fragment。请注意,像 ?&/ 这样的字符没有被编码。

更多信息,请参见帖子:Java中的HTTP URL地址编码如何编码URL以避免特殊字符在Java中


编辑

由于您的输入是字符串URL,使用URI的参数化构造函数之一将无法帮助您。也不能直接使用new URI(strUrl),因为它不引用URL参数。

因此,在这个阶段我们必须使用一个技巧来得到你想要的:

public URL parseUrl(String s) throws Exception {
     URL u = new URL(s);
     return new URI(
            u.getProtocol(), 
            u.getAuthority(), 
            u.getPath(),
            u.getQuery(), 
            u.getRef()).
            toURL();
}

在使用这个例程之前,您必须对字符串进行清理,以确保它表示一个绝对的URL。这里有两种方法:

  1. 猜测。将http://添加到字符串前面(除非已经存在)。

  2. 从上下文中使用new URL(URL context, String spec)构建URI。


1
URI uri = new URI("www.google.com"); uri.toURL(); -> 异常: "URI 不是绝对路径" - Arutha
3
这不是一个有效的URI。请使用正确的“协议方案”,例如http。 - Johan Sjöberg
3
@Arutha,这并不能使其更加正确。这意味着你必须自己清理URL。 - Johan Sjöberg
好技巧!我现在正在使用它来编码我的Wordnik库中的URL。谢谢! - Jeremy Brooks
这对我没用。我有一个像这样的URL:https:/x.com/api/val/?p=q&start=2015-04-30T23:59:59Z&rows=10&page=1 我需要查询中的冒号进行编码,而您通过新的URL和URI进行的传输并没有实现它。有什么想法吗? - Julian

3

所以你的意思是想要对URL的部分内容进行编码,而不是整个URL。听起来你需要将URL拆分成几部分,将需要编码的部分通过编码器进行编码,然后重新组合以得到完整的URL。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接