我正在使用来自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编码字节序列。
我彻底迷失了,任何帮助都会非常感激。
答案 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");
}
现在我主张试图让罗马图书馆做好照顾,但如果一切都失败了,这将是一种方法。