在使用JAXB unmarshal XML的时候碰到了一个异常: Invalid byte 1 of 1-byte UTF-8 sequence
public static Object unmarshal(InputStream xml, Class> clazz) {
Object obj = null;
try {
JAXBContext jc = JAXBContext.newInstance(clazz.getPackage().getName());
Unmarshaller u = jc.createUnmarshaller();
obj = u.unmarshal(xml);
} catch (JAXBException e) {
throw new RuntimeException("Can't unmarshal this xml file, please check the error message: " + e.getMessage());
}
return obj;
}
问题出现在u.unmarshal(xml)这个地方,这句实际上调用的是SaxParser.parse()方法,这是一个encoding的问题,我们需要将输入流转换为UTF-8格式,然后再由SaxParser去解析该输入流, 解决方法如下:
public static Object unmarshal(InputStream xml, Class> clazz) {
Object obj = null;
try {
JAXBContext jc = JAXBContext.newInstance(clazz.getPackage().getName());
Unmarshaller u = jc.createUnmarshaller();
Reader reader = new InputStreamReader(xml,"UTF-8");
InputSource is = new InputSource(reader);
is.setEncoding("UTF-8");
obj = u.unmarshal(is);
} catch (JAXBException e) {
throw new RuntimeException("Can't unmarshal this xml file, please check the error message: " + e.getMessage());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Doesn't support encoding: UTF-8, please check the error message: " + e.getMessage());
}
return obj;
}
下面将使用泛型进一步优化该方法:
public static T unmarshal(InputStream xml, Class clazz) {
T obj = null;
try {
JAXBContext jc = JAXBContext.newInstance(clazz.getPackage().getName());
Unmarshaller u = jc.createUnmarshaller();
Reader reader = new InputStreamReader(xml,"UTF-8");
Source source = new StreamSource(reader);
JAXBElement element = u.unmarshal(source, clazz);
obj = element.getValue();
} catch (JAXBException e) {
throw new RuntimeException("Can't unmarshal this xml file, please check the error message: " + e.getMessage());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Doesn't support encoding: UTF-8, please check the error message: " + e.getMessage());
}
return obj;
}