在java中从URL读取UTF-8编码的XML

时间:2012-05-23 15:49:30

标签: java url utf-8

我正在尝试从Google天气网络服务中读取XML数据。响应包含一些西班牙语字符。问题是这些字符没有正确显示。我试图将所有内容转换为UTF-8,但这似乎没有帮助。代码如下:

public static void main(String[] args) {
    try {
    URL url = new URL("http://www.google.com/ig/api?weather=Noja&hl=es");
    HttpURLConnection con = (HttpURLConnection) url.openConnection();

    BufferedReader in = new BufferedReader(new InputStreamReader(
    con.getInputStream(), "UTF-8"));
    String str = in.readLine();
    //this does not work even                        
    //String str = new String(in.readLine().getBytes("UTF-8"),"UTF-8");
    System.out.println(str);

    in.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
}

下面给出了输出(修剪以使帖子保持在限制范围内)。注意“mi ”和s b

修剪以保持最大字符数限制

<day_of_week data="mi�"/><day_of_week data="s�b"/><low data="11"/><high data="16"/><icon data="/ig/images/weather/chance_of_rain.gif"/><condition data="Posibilidad de lluvia"/></forecast_conditions></weather></xml_api_reply>

2 个答案:

答案 0 :(得分:1)

您的输入可能是正确的,虽然我会使用XML解析器来读取XML,而不是尝试将其解释为逐行提要。但是您的输出可能不正确。

  1. JVM的默认字符编码是什么?检查(并设置)容易混淆的属性-Dfile.encoding=UTF-8
  2. 您的系统上是否存在必需的字体等?你能检查一下你输出的实际字符代码而不是依赖你的终端设置吗?我怀疑情况可能就是这样,因为编码/解码似乎有效,而你只是错过了那些个别角色。

答案 1 :(得分:1)

如果该页面是xml,那么通常应该将InputStream直接传递给xml解析器并让它自动检测编码。否则,您应该查看content type response header的charset参数以确定正确的编码并创建相应的InputStreamReader。

编辑:该服务器确实使用不同的浏览器和java客户端编码进行响应,可能取决于Accept-Charset请求标头。对于firefox,此标头具有值

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n

这意味着两个字符集都被接受,任何一个都没有偏好。服务器使用Content-Type标头text/xml; charset=UTF-8进行响应。 java客户端不发送此标头,服务器以text/xml; charset=ISO-8859-1响应。

要使用服务器提供的字符集,您可以使用以下代码:

Matcher matcher = Pattern.compile("charset\\s*=\\s*([^ ;]+)").matcher(contentType);
String charset = "utf-8"; // default
if (matcher.find()) {
    charset = matcher.group(1);
}
System.out.println(con.getContentType());

BufferedReader in = new BufferedReader(new InputStreamReader(
    con.getInputStream(), charset));

编辑2:关闭服务器根据用户代理标头决定要使用的字符集。如果添加以下行,则会使用utf-8的字符集进行响应。

con.setRequestProperty("User-Agent", "Mozilla/5.0");

无论如何,Content-Type响应头包含要使用的正确字符集。