Java Unicode查询参数的Punycode

Java Unicode查询参数的Punycode,java,url,unicode,punycode,Java,Url,Unicode,Punycode,我正在尝试用Punycode对一些Unicode URL进行编码。这些URL具有包含非ASCII字符的查询参数,例如: https://en.wiktionary.org/w/index.php?title=Clœlia&printable=yes 问题是,当我尝试用Java实现时,结果URL是错误的: String link = "https://en.wiktionary.org/w/index.php?title=Clœlia&printable=yes"; link =

我正在尝试用Punycode对一些Unicode URL进行编码。这些URL具有包含非ASCII字符的查询参数,例如:

https://en.wiktionary.org/w/index.php?title=Clœlia&printable=yes
问题是,当我尝试用Java实现时,结果URL是错误的:

String link = "https://en.wiktionary.org/w/index.php?title=Clœlia&printable=yes";
link = IDN.toASCII(link);

// -> link = http://en.wiktionary.org/w/index.xn--php?title=cllia&printable=yes-hgf
如果我这样做,结果字符串是不同的(我不知道为什么),但也是错误的:

String link = "http://en.wiktionary.org/w/index.php?title=" + IDN.toASCII("Clœlia") + "&printable=yes";

// -> link = http://en.wiktionary.org/w/index.php?title=xn--cllia-ibb&printable=yes
如果我从Chrome复制地址并粘贴到这里,我会得到这个URL,这就是我想要的:

https://en.wiktionary.org/w/index.php?title=Cl%C5%93lia&printable=yes

我在这里做错了什么?

你做错了的是使用punycode。Punycode仅用于域名,包括URL的域名部分

URL的其他部分,包括查询参数部分,也被称为URL编码或URI编码,这就是Chrome所做的;这将以UTF-8编码非ASCII Unicode字符,然后使用百分号(%)和两个十六进制数字编码不在有限ASCII子集中的所有八位字节;UTF-8用于非ASCII的八位字节80-FF始终采用%编码。 确切地说,查询参数部分通常和其他部分有时使用为HTML表单提交定义的微小变量,如
application/x-www-form-urlencoded
;这将空间编码为加号“+”而不是%20,这是明确的,因为“+”已经在不安全的集合中,因此编码为%2B

在Java中,为此使用
Java.net.URLEncoder.encode
Java.net.urldecode.decode
;为了获得可靠的结果,请使用编码名为“UTF-8”的较新的2-arg表单