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方法,谢谢。

 


posted on 2022-02-15 14:39  MrQuan  阅读(2134)  评论(0编辑  收藏  举报