如何正确编码这个URL
我正在尝试使用JSoup来获取此URL
http://betatruebaonline.com/img/parte/330/CIGUEÑAL.JPG
即使使用编码,我也有一个例外。 我不明白为什么编码是错误的。 它返回
http://betatruebaonline.com/img/parte/330/CIGUEN%C3%91AL.JPG
而不是正确的
http://betatruebaonline.com/img/parte/330/CIGUEN%CC%83AL.JPG
我如何解决这个问题? 谢谢。
private static void GetUrl()
{
try
{
String url = "http://betatruebaonline.com/img/parte/330/";
String encoded = URLEncoder.encode("CIGUEÑAL.JPG","UTF-8");
Response img = Jsoup
.connect(url + encoded)
.ignoreContentType(true)
.execute();
System.out.println(url);
System.out.println("PASSED");
}
catch(Exception e)
{
System.out.println("Error getting url");
System.out.println(e.getMessage());
}
}
编码没有错,这里的问题是复合unicode和预编码字符“Ñ”的Unicode可以用2种方式显示,它们看起来相同但是真的不同
precomposed unicode: Ñ -> %C3%91
composite unicode: N and ~ -> N%CC%83
我强调,两者都是正确的,这取决于你想要哪种类型的unicode:
String normalize = Normalizer.normalize("Ñ", Normalizer.Form.NFD);
System.out.println(URLEncoder.encode("Ñ", "UTF-8")); //%C3%91
System.out.println(URLEncoder.encode(normalize, "UTF-8")); //N%CC%83
这里发生了什么?
正如@yelliver所说,webserver似乎在其路径名中使用了NFD编码的unicode。 所以解决方案是使用相同的编码。
网络服务器是否正确?
1.对于那些好奇的人(像我),这篇关于多语言Web地址的文章为这个主题带来了一些启发。 在关于IRI程序的部分(实际由网络服务器处理的部分)中,它指出:
尽管域名注册管理机构可以同意接受特定形式的域名和编码(基于ASCII码的punycode),但多脚本路径名称标识位于多种平台上的资源,这些平台的文件系统会继续使用许多不同的平台编码。 这使得路径比域名更难处理。
2.更多关于如何编码pathes受试者可以在5.3.2.2节中找到。 在IETF关于国际化资源标识符(IRIs)的建议标准rfc3987。 它说:
IRI的等价性必须依赖于IRI在适当的预字符标准化的假设,而不是在比较两个IRI时应用字符标准化。 例外情况是从非数字形式转换,以及从非基于UCS的字符编码转换为基于UCS的字符编码。 在这些情况下,使用NFC的NFC或标准化代码转换器必须用于互操作性。 为了避免错误的消极处理和代码转换问题, 应该使用NFC创建IRI 。 使用NFKC可能会避免更多问题; 例如,通过选择半角拉丁字母而不是全角字母,全角而不是半角片假名。
3. Unicode联盟指出:
NFKC是标识符的首选形式,特别是在存在安全问题的情况下(见UTR#36)。 NFD和NFKD对于内部处理最为有用。
结论
问题中提到的网络服务器不符合IRI标准或unicode联盟的建议,并使用NFD编码代替NFC或NFKC。 正确编码URL-String的一种方法如下
URI uri = new URI(url.getProtocol(), url.getUserInfo(), IDN.toASCII(url.getHost()), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
然后将该Uri转换为ASCII字符串:
String correctEncodedURL=uri.toASCIIString();
toASCIIString()
调用使用NFC编码的unicode的encode()
。 IDN.toASCII()
将主机名转换为Punycode。
非常简单的解决方案:编码系统提供,您需要的是不同的,以下解决方案将对您有所帮助。
private static void GetUrl(String url)
{
try
{
String encodedurl = url.replace("Ñ","N%CC%83");
Response img = Jsoup
.connect(encodedurl)
.ignoreContentType(true)
.execute();
System.out.println(url);
System.out.println("PASSED");
}
catch(Exception e)
{
System.out.println("Error getting url");
System.out.println(e.getMessage());
}
}
链接地址: http://www.djcxy.com/p/41131.html