特定的XML数据乱码

时间:2016-05-15 23:53:51

标签: java xml character-encoding rss

我正在使用来自kat.cr的RSS源作为个人项目。我试图使用Rome框架阅读Feed并遇到了一个重大问题。

我尝试使用罗马的所有其他Feed(以及其他更基本的阅读Feed的方式)完全正常,但是,以下Feed继续投掷字符编码相关的例外。

https://kat.cr/usearch/Arrow%20S04E21/?field=seeders&sorder=desc&rss=1

然后,我创建了以下方法,以查看接收到的数据:

public static void saveXML(String url) throws IOException {
    Client client = ClientBuilder.newClient();
    Response r = client.target(url).request(MediaType.TEXT_PLAIN_TYPE).get();

    PrintWriter out = new PrintWriter("XML.txt");
    String sXML = r.readEntity(String.class);
    out.print(sXML);
    out.close();
}

上述Feed会导致数据乱码,而所有其他Feed都会显示出来。 为什么即使字符集被强制为UTF-8,它也能在任何浏览器中完美显示?

我查看了Hexplorer中的'XML.txt'文件,注意到整个文件中的UTF-8编码字节序列。

我彻底迷失了,任何帮助都会非常感激。

1 个答案:

答案 0 :(得分:0)

您收到的内容使用GZip格式进行压缩。

现在我打算用一种解决问题的方法写出更好的答案,但是你的方法导致String,此时你可能已经改变了服务器的原始字节,导致转换为不行。我对罗马框架一无所知,或者如何让它为你返回字节或解压缩。但假设你有一些压缩的gzip字节,你可以这样做:

public static String decompress(byte [] data) throws IOException {
    try (
        GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(data));
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ) {

        int read;
        byte [] buff = new byte[1024];
        while((read = gis.read(buff)) != -1) {
            out.write(buff, 0, read);
        }

        return out.toString("UTF-8");
    }
}

您可以尝试使用

String sXML = r.readEntity(String.class);
return decompress(sXML.getBytes());

但如果有效,我会感到惊讶。也许你可以做到

String sXML = r.readEntity(byte[].class);
return decompress(sXML.getBytes());

但我再也不知道罗马框架是如何做事的。

修改

您还可以查找GZIP文件签名。我查看了本网站的文件签名 - http://www.garykessler.net/library/file_sigs.html,但您可以在很多地方查找。假设您有来自响应的字节,您可以执行以下操作:

String sXML = r.readEntity(byte[].class);
// check for gzip encoding using signature
if(sXML.length > 3 && 
   sXML[0] == (byte)0x1F && 
   sXML[1] == (byte)0x8B && 
   sXML[2] == (byte)0x08) {
    // Is gzip encoded, decode it.
    return new String(decompress(sXML), "UTF-8");
} else {
    return new String(sXML, "UTF-8");
}

现在我主张试图让罗马图书馆做好照顾,但如果一切都失败了,这将是一种方法。