xml文件在本地是以UTF-8编码进行保存的,里面有一些中文字符串,通过以下反序列化代码生成了JAVA对象
JAXBContext jaxbContext ; Object object = null ; try { jaxbContext = JAXBContext.newInstance(clazz); //jaxbContext = JAXBContext.newInstance(Logic.class); //ClassLoader classLoader = Thread.currentThread().getContextClassLoader() ; StreamSource stremSource = new StreamSource(inputStream) ; //反序列化 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller() ; object = unmarshaller.unmarshal(stremSource) ; }catch(Exception e){ e.printStackTrace(); return null ; } return object ;
通过观察,发现反序列化后产生的JAVA对象中的字符串属性的字符编码在WEB环境下都变成与当前JAVA执行环境所处的字符编码集,也就是说此时对象中的字符编码已变为与执行环境中的编码相同。此时如果要对对象进行序列化(即重新生成为XML文件),必须要保证序列化时设置编码属性与当前对象中的编码相同,否则保存的XML文件中就会出现乱码
String xml = null;
JAXBContext context;
ByteArrayOutputStream outputStream = null ;
try {
context = JAXBContext.newInstance(clazz);
Marshaller m = context.createMarshaller();
//m.setProperty(Marshaller.JAXB_ENCODING, encoding);
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//设置转换编码
m.setProperty(Marshaller.JAXB_ENCODING, charsetName);
//document level event
m.setProperty(Marshaller.JAXB_FRAGMENT, false);
if( schemaLocation != null && schemaLocation.trim()!=""){
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
}
outputStream = new ByteArrayOutputStream();
m.marshal(object, outputStream);
xml=outputStream.toString(charsetName);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(outputStream != null){
try {
outputStream.close() ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return xml ;
JAXBContext context;
ByteArrayOutputStream outputStream = null ;
try {
context = JAXBContext.newInstance(clazz);
Marshaller m = context.createMarshaller();
//m.setProperty(Marshaller.JAXB_ENCODING, encoding);
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//设置转换编码
m.setProperty(Marshaller.JAXB_ENCODING, charsetName);
//document level event
m.setProperty(Marshaller.JAXB_FRAGMENT, false);
if( schemaLocation != null && schemaLocation.trim()!=""){
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
}
outputStream = new ByteArrayOutputStream();
m.marshal(object, outputStream);
xml=outputStream.toString(charsetName);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(outputStream != null){
try {
outputStream.close() ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return xml ;
注:通过System.getProperty("file.encoding")可以获知当前执行环境的编码。通过该属性发现有时WEB环境下和测试用例环境下编码会不一样,这就会导致有时测试正常,实际环境下运行出现乱码的原因。
总结:掌握两个原则(1)用JAXB转XML为对象时,会转对象编码为本地JAVA环境的字符编码
(2) 用JAXB转对象为XML时,默认会转为UTF-8编码,所以要保证不出乱码,转的时候应指定转为与本地JAVA环境相同的字符编码,或者保证在转的时候同时指定文件编码和转换的输出流编码一致。