JAXB错误的说明:1字节UTF-8序列的字节1无效

时间:2010-06-14 18:51:18

标签: java xml encoding utf-8 jaxb

我们正在使用JAXB解析XML文档并收到此错误:

[org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence.]
at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)

这究竟是什么意思,我们如何解决这个问题?

我们正在执行以下代码:

jaxbContext = JAXBContext.newInstance(Results.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema(getSchema());
results = (Results) unmarshaller.unmarshal(new FileInputStream(inputFile));

更新

问题似乎是由于XML文件中的这个“有趣”字符:¿

为什么会导致这样的问题?

更新2

文件中有两个奇怪的字符。它们位于文件的中间。请注意,该文件是基于数据库中的数据创建的,并且这些奇怪的字符以某种方式进入数据库。

更新3

以下是完整的XML代码段:

<Description><![CDATA[Mt. Belvieu ¿ Texas]]></Description>

更新4

请注意,没有<?xml ...?>标头。

特殊字符的HEX是BF

3 个答案:

答案 0 :(得分:3)

所以,你的问题是当你的文件使用其他编码时,JAXB将没有<?xml ...?>标题的XML文件视为UTF-8(如果0xBF,则可能是ISO-8859-1或Windows-1252字符实际上意味着¿)。

如果您可以更改文件的生产者,可以添加<?xml ...?>标头和实际编码规范,或者只使用UTF-8编写文件。

如果无法更改生成器,则必须使用InputStreamReader和明确的编码规范,因为(不幸的是)JAXB不允许更改其默认编码:

results = (Results) unmarshaller.unmarshal(
   new InputStreamReader(new FileInputStream(inputFile), "ISO-8859-1")); 

但是,这个解决方案很脆弱 - 它在带有<?xml ...?>标头且具有不同编码规范的输入文件上失败。

答案 1 :(得分:1)

这可能是Byte Order Mark (BOM),并且是UTF文件开头的特殊字节序列。坦率地说,它们是屁股的痛苦,在与.net系统交互时似乎特别常见。

尝试重新编写代码以使用Reader而不是InputStream

results = (Results) unmarshaller.unmarshal(new FileReader(inputFile));

Reader可识别UTF,可能会更好地刺激它。更简单地说,将File直接传递给Unmarshaller,让JAXBContext担心它:

results = (Results) unmarshaller.unmarshal(inputFile);

答案 2 :(得分:0)

听起来好像你的XML是用UTF-16编码的,但是这个编码没有传递给Unmarshaller。使用Marshaller你可以使用marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-16");来设置它,但是因为Unmarshaller不需要支持任何属性,我不确定除了确保你的XML文档在encoding="UTF-16"中有<?xml?>之外的其他方法。 1}}元素。