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環境相同的字符編碼,或者保證在轉的時候同時指定文件編碼和轉換的輸出流編碼一致。
