Java對象轉xml字符串


需求主要是用於數據的傳輸,系統先將所需數據以對象形式封裝填充出來,然后再由對象轉為xml

1,首先定義一個接口,定義一個創建xml的方法

public interface IFileCreateService {
FileReturnModel createFile(Object object) throws MessageConvertException;
}

2,接下來是實現方法

@Override
public FileReturnModel createFile(Object object) throws MessageConvertException {
FileReturnModel fileReturnModel = new FileReturnModel();
XMLOutputFactory factory = XMLOutputFactory.newInstance();
StringWriter sw = new StringWriter();
XMLStreamWriter writer = null;
try {
writer = factory.createXMLStreamWriter(sw);
createTitle(writer);
createBody(writer, object);
} catch (XMLStreamException e) {
e.printStackTrace();
throw new MessageConvertException("報文轉換異常 XMLStreamException", e);
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new MessageConvertException("報文轉換異常 IllegalAccessException", e);
} catch (NoSuchMethodException e) {
e.printStackTrace();
throw new MessageConvertException("報文轉換異常 NoSuchMethodException", e);
} catch (InvocationTargetException e) {
e.printStackTrace();
throw new MessageConvertException("報文轉換異常 InvocationTargetException", e);
} catch (Exception e) {
e.printStackTrace();
throw new MessageConvertException("報文轉換異常 NoSuchFieldException", e);
} finally {
try {
if (null != writer) {
writer.flush();
writer.close();
fileReturnModel.setFileContext(sw.toString());
}
} catch (XMLStreamException e) {
e.printStackTrace();
throw new MessageConvertException("報文轉換異常 流關閉錯誤 XMLStreamException", e);
}
}
return fileReturnModel;
}
3,createTitle()方法作用是編寫標題信息,也就是xml頭部信息,定義約束
protected void createTitle(XMLStreamWriter writer) throws XMLStreamException {
writer.writeStartDocument("UTF-8", "1.0");
// writer.writeCharacters("\n");
}
4,createBody()方法
private void createBody(XMLStreamWriter writer, Object obj) throws XMLStreamException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException,UnsupportedEncodingException,NoSuchFieldException {
if (obj.getClass().isAnnotationPresent(Model.class)) {
Model model = obj.getClass().getAnnotation(Model.class);
writer.writeStartElement(model.name());
writeXmlBody(writer, obj.getClass(), obj);
writer.writeEndElement();
}
}
紅色字體的Model是定義的@Model注解,用於擴展屬性,如下圖,model.name()就是"CONTRACT"

 

 

 

 5,writeXmlBody()方法編寫具體的標簽及屬性

protected void writeXmlBody(XMLStreamWriter writer,Class clas, Object object) throws XMLStreamException, IllegalArgumentException, IllegalAccessException, SecurityException, NoSuchMethodException, InvocationTargetException, UnsupportedEncodingException, NoSuchFieldException {
Field[] fields = clas.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Property propertyAnnotation = field.getAnnotation(Property.class);
if (null == propertyAnnotation){
continue;
}
if (Collection.class.isAssignableFrom(field.getType())) {//集合
Collection collection = (Collection) field.get(object);
if (collection != null) {
for (Object objInner : collection) {
writeXmlBody(writer, objInner.getClass(),objInner);
}
}
} else if (Date.class.isAssignableFrom(field.getType())) {//日期
Date date = (Date) field.get(object);
writer.writeStartElement(propertyAnnotation.name());
writer.writeCharacters(formateDate(date));
writer.writeEndElement();

} else if (String.class.isAssignableFrom(field.getType())||Double.class.isAssignableFrom(field.getType())||Integer.class.isAssignableFrom(field.getType())||Float.class.isAssignableFrom(field.getType())||Character.class.isAssignableFrom(field.getType())|| BigDecimal.class.isAssignableFrom(field.getType())) {
writer.writeStartElement(propertyAnnotation.name());
writer.writeCData(fillData(field.get(object)));
writer.writeEndElement();
} else if(byte[].class.isAssignableFrom(field.getType())){//字節
writer.writeStartElement(propertyAnnotation.name());
if(null!=field.get(object)){
byte[] bytes= (byte[]) field.get(object);
writer.writeCData(new String(bytes,"GBK"));
}else{
writer.writeCData("");
}
writer.writeEndElement();
}
else {//類對象
Object obj = field.get(object);
if(!"model".equals(field.getName())){
writer.writeStartElement(propertyAnnotation.name());
}
if (null != obj) {
writeXmlBody(writer, obj.getClass(),obj);//這里使用了遞歸
//加載父類的屬性
writeXmlBody(writer, obj.getClass().getSuperclass(),obj);
}
if(!"model".equals(field.getName())) {
writer.writeEndElement();
}
}
}
}
需要注意,由於示例中,我給Contract對象使用了@Model注解,其成員變量,我使用@Property注解,那么在writeXmlBody()方法中,我編寫xml取的是注解中的屬性,也就是說大寫的CONTRACT,
CONTRACTCODE。轉化后的結果是這樣的

 

 

 如果不適用注解屬性,使用對象原本的屬性,則 propertyAnnotation.name() 需要替換成 field.getName(),轉化后的結果是這樣的

 

 
        

 6,方法中使用遞歸的作用是循環遍歷類對象中的所有子類對象,孫類對象,重孫對象等等,就是嵌套。方法大致是這些,需要引入對應的依賴,注意異常的捕獲及流的釋放等,以上代碼是個人編寫過使用過,這里記錄一下便於以后快速記起,也希望小伙伴們能給出更好的對象轉xml方法,謝謝。

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM