带有中文字符的URI无效(Java)

3

在设置带有中文字符的URL连接时遇到了问题。使用拉丁字符可以正常工作:

String xstr = "维也纳恩斯特哈佩尔球场" ;
URI uri = new URI("http","ajax.googleapis.com","/ajax/services/language/detect","v=1.0&q="+xstr,null);   
URL url = uri.toURL(); 
URLConnection connection = url.openConnection();
InputStream is = connection.getInputStream() ;

调用getInputStream()会得到以下结果:
java.lang.IllegalArgumentException: Invalid uri 'http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&q=???????????': Invalid query

奇怪,我做了一个小的JUnit测试用例,没有得到那个异常。我正在运行java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9.4) (6b20-1.9.4-0ubuntu1) OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)。你确定你的.java文件编码是UTF-8吗? - hleinone
我很确定——只要通过了那一步,字符就会按预期进入数据存储区。在谷歌搜索时,我发现了一个 Oracle 页面 http://download.oracle.com/javase/1.4.2/docs/api/java/net/URI.html ,其中指出可接受的字符为“……不在 US-ASCII 字符集中的 Unicode 字符,不是控制字符(根据 Character.isISOControl 方法),也不是空格字符(根据 Character.isSpaceChar 方法)(与 RFC 2396 不同,后者仅限于 US-ASCII)。所以可能这取决于实现方式?我的是 Android。 - Joe Knapp
5个回答

8

这个问题是由于URI.toURL()没有对非ASCII字符进行百分号编码所致。请改用以下代码:

URL url = new URL(uri.toASCIIString());  

嘿,我出去铲车道几分钟,回来后我的问题就被回答了。我喜欢这个网站... - Joe Knapp
3
您可以使用以下代码来实现相同的结果:String xstr = URLEncoder.encode("维也纳恩斯特哈佩尔球场", "utf-8"); URL url = new URL("http","ajax.googleapis.com","/ajax/services/language/detect?v=1.0&q="+xstr); - hleinone
经过进一步测试,发现URLEncoder比toASCIIString更适合此目的。当字符串包含方括号时,后者会失败,因为它会保留方括号,而这在URL中是不合法的。 - Joe Knapp
@hleinone 为什么我们使用 utf-8?这是什么标准?谢谢~ - Alston

2

axtavt的回答让我免于疯狂,谢谢!只有一个评论(我不知道如何在答案下方进行评论:)

如果您以URL开头,则需要在构建URI之前对引号进行编码:

String s = "your_url?with=\"quotes\"";
URI su = new URI (s.replaceAll("\"", "%22");
URL ur = new URL( su.toASCIIString());

0

我认为这与“UTF-8”字符集有关。请查看此主题以了解更多信息,还有Java中的中文


0
根据URI RFC(参见第2.4节),URI中不允许使用非美国ASCII字符,必须对其进行编码。

0

下载带有特殊字符的图像 URL。下面的代码段展示了如何从带有特殊字符的 URL 中读取图像属性。

  • 使用实际的 IP 地址和端口号替换 <IP> 和 <port>。

  • 如果您使用的是域名,可以使用域名替换 :。

  • 用您自己的文件路径替换 <file_path>。

     try {
         String fileName = "pexels-martin-péchy-1866149%20(1).jpg";
         URI uri = new URI("http://<IP>:<port>/<file_path>/" + fileName);
         URL url = new URL(uri.toASCIIString());
         BufferedImage image = ImageIO.read(url);
         int height = image.getHeight();
         int width = image.getWidth();
    
    
         System.out.println("图片下载成功!: " + url.toString()+" 高度: "+height);
     } catch (Exception e) {
         e.printStackTrace();
     }
    

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