java list对象转 xml_将List<T>生成XML文档(字串),将XML文档(字串)解析成List<T>,适用于任何对象的...

本文介绍了一种高效的方法,用于将Java对象如`Person`和`Location`转换为XML字符串,并将XML字符串解析回相应的对象列表。通过自定义的`BeanModel2`类,可以支持基本类型、Timestamp以及包含id属性的自定义对象。XML转换过程包括对象属性到XML的映射,以及XML字符串到对象的反向解析,实现了Java对象与XML之间的双向转换。
摘要由CSDN通过智能技术生成

很多刚开始涉猎web开发的猿友可能会遇到一个情况,就是将服务器端的数据传回前端,如果前端是浏览器的话是没有什么问题的,把服务器的各种对象属性通过OGNL或者JSTL等等很轻松的呈现出来。可如果前端是JavaSE开发的桌面应用或者Android应用,就比较麻烦了。

这时我们只能传回去一些Header或者Content,也就是头和字串,所以也就产生了把字串格式规划好,传回去然后按照一定的规则解析出来,得到需要的属性,而我们常用的无非是XML与JSON两种格式数据。

对于JSON与XML在性能与格式上各有优点,XMl格式统一,符合标准,安全,缺点就是格式复杂,前后端解析需要大量的代码,JSON的话格式简单,易于读写,但是相对XML通用性还不是特别强。

使用XML传输对象的时候,往往我们需要将一个对象的各种属性转化成字符串构建成一个XML,然后解析的时候再将XML文件或者字符串取出来,赋值给对象的属性,由此生成一个具有有效属性的对象。

而每个对象的属性必然是不同的,所以经常我们会为每个对象写一套解析方法,所以庞大的代码工作量就产生了,那么有没有简单一点的方法呢?我是这样做的,话不多说,先上效果图。

public class Person {

static final private String SPLIT_MARK = "#";

private int id;

private String username;// 账号

private String password;// 密码

private String name;// 名称

private String bound;// 绑定

...

}

执行代码

public static void main(String[] args) {

Person person = new Person();

person.setId(2);

person.setName("xiao南瓜");

person.setUsername("abc");

person.setPassword("123");

person.setBound("!@#");

String sXml=ParseList(Arrays.asList(person), Person.class);

System.out.println(sXml);

}

结果

07f501d0bde6720a9ad78c11f3c84d14.png

图截取不下来,在文件中或者浏览器格式是很好的,把输出结果给大家复制出来看

<_persons><_person>2abc123xiao南瓜!@#

然后再将生成的xml字符串转回对象

public static void main(String[] args) {

Person person = new Person();

person.setId(2);

person.setName("xiao南瓜");

person.setUsername("abc");

person.setPassword("123");

person.setBound("!@#");

String sXml = ParseList(Arrays.asList(person), Person.class);

List persons = ParseXML(sXml, Person.class);

Person person2 = persons.get(0);

System.out.println(person);

System.out.println(person2);

}

结果(重写的toString方法)

b5c92612f6d80a3b9a880a82e17e9417.png

这就是List与XML的正向逆向解析,如果是一个对象就将这个对象转换为List即可。

再测试一个Java对象

public class Location {

private int id;

private double longi;// 经度

private double lati;// 纬度

private String address;// 位置描述

private Timestamp lastTime;// 最后修改时间

private String recordPath;// 位置记录存储路径

private Person person;// 何人的位置

...

}

public static void main(String[] args) {

Person person=new Person();

person.setId(7);

Location location=new Location();

location.setId(3);

location.setLongi(12.34);

location.setLati(56.78);

location.setLastTime(new Timestamp(System.currentTimeMillis()));

location.setAddress("山西");

location.setRecordPath("F:\\");

location.setPerson(person);

String sXml=ParseList(Arrays.asList(location), Location.class);

List locations=ParseXML(sXml, Location.class);

Location location2=locations.get(0);

System.out.println(location);

System.out.println(location2);

}

结果

7311e2e2b4534196c443ea8c24272795.png

这些自定义的JavaBean有一些特点需要记住

1.所有属性只能是8种基本类型,即byte,short,int,long,float,double,boolean,String以及Timestamp。

2.可以有其他类型对象作为属性,但其他类型对象也必须符合这些规则。

3.对象中必须有id属性,名字必须是id且必须是int类型,这是为了标识null对象与标识其他对象(外键)做的。

4.null对象也会解析成xml,只不过id为-1,表示null对象,当然如果xml中如果有id属性为-1的也会解析成null对象。

5.所有外键(其他自定义的对象作为属性)在xml中只会保存id属性,为了防止外键为自己时的无限迭代。

因为我们服务器的大多数Bean都是数据库来的,或者存或者取,所以虽然支持的类型不多,不过也应该够用了。前台用的话只要把响应的Bean的class与这个模型拷贝过去即可。

希望能帮助大家。

如果有什么不对或者更好的建议,希望大家提出来,谢谢,因为是第一次写,不足之处多多指教。

模型源码,使用方式以及思路注释里都有

public class BeanModel2 {

private static final String ATTR_ID = "id";// bean的id属性

private static final int NULL_ID = -1;

// 根据bean自动构建xml的root名字

public static String GetRootName(Class> bean) {

String root_name = "_" + bean.getSimpleName().toLowerCase() + "s";

return root_name;

}

// 根据bean自动构建xml的child名字

public static String GetElemName(Class> bean) {

String elem_name = "_" + bean.getSimpleName().toLowerCase();

return elem_name;

}

// 根据bean和field构建xml中child的attribute名字

public static String GetAttrName(Class> bean, Field field) {

String attr_name = bean.getSimpleName().toLowerCase() + "_"

+ field.getName();

return attr_name;

}

// 根据field与element获取此field对应的value

@SuppressWarnings("finally")

public static String GetAttrValue(Field field, T elem) {

String value = "";

try {

Class> type = field.getType();// 获取此field的类型

/*

* 下面依次处理 八种基本类型 Timestamp类型 其他类型(带有id属性的bean类型)

*/

if (type.equals(Byte.class) || type.equals(byte.class)) {

value = field.getByte(elem) + "";

} else if (type.equals(Short.class) || type.equals(short.class)) {

value = field.getShort(elem) + "";

} else if (type.equals(Integer.class) || type.equals(int.class)) {

value = field.getInt(elem) + "";

} else if (type.equals(Long.class) || type.equals(long.class)) {

value = field.getLong(elem) + "";

} else if (type.equals(Float.class) || type.equals(float.class)) {

value = field.getFloat(elem) + "";

} else if (type.equals(Double.class) || type.equals(double.class)) {

value = field.getDouble(elem) + "";

} else if (type.equals(Boolean.class) || type.equals(boolean.class)) {

value = field.getBoolean(elem) + "";

} else if (type.equals(String.class)) {

value = (String) field.get(elem);

} else if (type.equals(Timestamp.class)) {

value = ((Timestamp) field.get(elem)).getTime() + "";

} else {

// 如果这个类型有id这个属性,说明它是个外键

Field attr_id = type.getDeclaredField(ATTR_ID);

// 并且此属性不为null

if (attr_id != null && field.get(elem) != null) {

attr_id.setAccessible(true);

value = attr_id.getInt(field.get(elem)) + "";

}

}

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} finally {

return value == null ? "" : value;

}

}

public static void SetAttrValue(Field field, T elem, String value) {

try {

Class> type = field.getType();

if (type.equals(Byte.class) || type.equals(byte.class)) {

try {

field.setByte(elem, Byte.parseByte(value));

} catch (NumberFormatException e) {

// 数字格式化异常,未做任何处理

}

} else if (type.equals(Short.class) || type.equals(short.class)) {

try {

field.setShort(elem, Short.parseShort(value));

} catch (NumberFormatException e) {

// 数字格式化异常,未做任何处理

}

} else if (type.equals(Integer.class) || type.equals(int.class)) {

try {

field.setInt(elem, Integer.parseInt(value));

} catch (NumberFormatException e) {

field.setInt(elem, NULL_ID);

}

} else if (type.equals(Long.class) || type.equals(long.class)) {

try {

field.setLong(elem, Long.parseLong(value));

} catch (NumberFormatException e) {

// 数字格式化异常,未做任何处理

}

} else if (type.equals(Float.class) || type.equals(float.class)) {

try {

field.setFloat(elem, Float.parseFloat(value));

} catch (NumberFormatException e) {

// 数字格式化异常,未做任何处理

}

} else if (type.equals(Double.class) || type.equals(double.class)) {

try {

field.setDouble(elem, Double.parseDouble(value));

} catch (NumberFormatException e) {

// 数字格式化异常,未做任何处理

}

} else if (type.equals(Boolean.class) || type.equals(boolean.class)) {

try {

field.setBoolean(elem, Boolean.parseBoolean(value));

} catch (Exception e) {

e.printStackTrace();

}

} else if (type.equals(String.class)) {

field.set(elem, value);

} else if (type.equals(Timestamp.class)) {

try {

field.set(elem, new Timestamp(Long.parseLong(value)));

} catch (NumberFormatException e) {

// 如果格式化异常,说明这个Timestamp是个null字串,当么它的值也为null

field.set(elem, null);

}

} else {

Field attr_id = type.getDeclaredField(ATTR_ID);

if (attr_id != null) {

attr_id.setAccessible(true);

Object external = type.newInstance();

try {

attr_id.setInt(external, Integer.parseInt(value));

field.set(elem, external);

} catch (NumberFormatException e) {

// 如果格式化出现异常,那么这个外键为null

field.set(elem, null);

}

}

}

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

}

}

public static String ParseList(List list, Class> bean) {

Document document = DocumentHelper.createDocument();// 获取document

document.setXMLEncoding("UTF-8");// 设置编码

Element root = document.addElement(GetRootName(bean));// 创建根元素

Field[] fields = bean.getDeclaredFields();// 获得bean的所有属性

for (T elem : list) {// 开始迭代传入的list

Element child = root.addElement(GetElemName(bean));// 创建子元素

for (Field field : fields) {// 迭代属性并且赋值

int mod = field.getModifiers();

if (Modifier.isFinal(mod) || Modifier.isStatic(mod)

|| Modifier.isPublic(mod)) {

continue;

}

field.setAccessible(true);// 打破封装性

String attr_name = GetAttrName(bean, field);// 获取bean属性对应的xml文件中的名字

String attr_value = GetAttrValue(field, elem);// 获取此属性对应的值

// System.out.println(attr_name+"="+attr_value);

child.addElement(attr_name).setText(attr_value);// 创建属性并赋值

}

}

return document.asXML();

}

@SuppressWarnings({ "unchecked", "finally" })

public static List ParseXML(String content, Class> bean) {

List elements = new ArrayList();// 构建一个空的list

try {

Document document = DocumentHelper.parseText(content);// 根据传入的content获取document

Element rootElement = document.getRootElement();// 获取根元素

Field[] fields = bean.getDeclaredFields();// 获取此bean的所有属性

// 迭代根元素下所有的子元素

for (Iterator childs = rootElement.elements().iterator(); childs

.hasNext();) {

T element = (T) bean.newInstance();// 根据bean创建一个对象

Element child = childs.next();// 依次获取子元素

for (Field field : fields) {

int mod = field.getModifiers();

if (Modifier.isFinal(mod) || Modifier.isStatic(mod)

|| Modifier.isPublic(mod)) {

continue;

}

field.setAccessible(true);

String attr_name = GetAttrName(bean, field);// 获取属性名

Element param = child.element(attr_name);

;// 根据属性名获取属性

String attr_value = param.getText();// 获取属性值

SetAttrValue(field, element, attr_value);// 设置属性值

// System.out.println("->"+attr_name+"="+attr_value);

}

// 判断该element是否==null?

Field field_id = bean.getDeclaredField(ATTR_ID);

if (field_id != null) {

field_id.setAccessible(true);

if (field_id.getInt(element) == NULL_ID) {

elements.add(null);

continue;

}

}

elements.add(element);// 把初始化好的element添加到elements中

}

} catch (SecurityException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (DocumentException e) {

e.printStackTrace();

} finally {

return elements;

}

}

/*

* 将一个文件读取出来解析成列表

*/

@SuppressWarnings("finally")

public static List ReadListByFile(String path, Class> bean) {

List elements = new ArrayList();// 构建一个空的list

try {

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(new File(path));

Element rootElement = document.getRootElement();// 获取根元素

Field[] fields = bean.getDeclaredFields();// 获取此bean的所有属性

// 迭代根元素下所有的子元素

for (Iterator childs = rootElement.elements().iterator(); childs

.hasNext();) {

T element = (T) bean.newInstance();// 根据bean创建一个对象

Element child = childs.next();// 依次获取子元素

for (Field field : fields) {

int mod = field.getModifiers();

if (Modifier.isFinal(mod) || Modifier.isStatic(mod)

|| Modifier.isPublic(mod)) {

continue;

}

field.setAccessible(true);

String attr_name = GetAttrName(bean, field);// 获取属性名

Element param = child.element(attr_name);

;// 根据属性名获取属性

String attr_value = param.getText();// 获取属性值

SetAttrValue(field, element, attr_value);// 设置属性值

// System.out.println("->"+attr_name+"="+attr_value);

}

// 判断该element是否==null?

Field field_id = bean.getDeclaredField(ATTR_ID);

if (field_id != null) {

field_id.setAccessible(true);

if (field_id.getInt(element) == NULL_ID) {

elements.add(null);

continue;

}

}

elements.add(element);// 把初始化好的element添加到elements中

}

} catch (Exception e) {

e.printStackTrace();

} finally {

return elements;

}

}

/*

* 将一个列表写入文件

*/

public static void WriteFileByList(String path, List list,

Class> bean) {

/*

* 从这里开始与ParseList是一样的

*/

Document document = DocumentHelper.createDocument();// 获取document

document.setXMLEncoding("UTF-8");// 设置编码

Element root = document.addElement(GetRootName(bean));// 创建根元素

Field[] fields = bean.getDeclaredFields();// 获得bean的所有属性

for (T elem : list) {// 开始迭代传入的list

Element child = root.addElement(GetElemName(bean));// 创建子元素

for (Field field : fields) {// 迭代属性并且赋值

int mod = field.getModifiers();

if (Modifier.isFinal(mod) || Modifier.isStatic(mod)

|| Modifier.isPublic(mod)) {

continue;

}

field.setAccessible(true);// 打破封装性

String attr_name = GetAttrName(bean, field);// 获取bean属性对应的xml文件中的名字

String attr_value = GetAttrValue(field, elem);// 获取此属性对应的值

// System.out.println(attr_name+"="+attr_value);

child.addElement(attr_name).setText(attr_value);// 创建属性并赋值

}

}

/*

* 这里就是把Parse的返回字串转化为了保存为文件而已

*/

FileOutputStream fos = null;

XMLWriter writer = null;

try {

fos = new FileOutputStream(path);

OutputFormat format = OutputFormat.createPrettyPrint();

format.setEncoding("UTF-8");

writer = new XMLWriter(fos, format);

writer.write(document);

writer.flush();

} catch (Exception e) {

e.printStackTrace();

} finally {

if (writer != null) {

try {

writer.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

public static void AddElementsByList(String path, List list,

Class> bean) {

SAXReader saxReader = new SAXReader();

Document document = null;

try {

document = saxReader.read(new File(path));

} catch (Exception e) {

e.printStackTrace();

return;

}

Element root = document.getRootElement();

Field[] fields = bean.getDeclaredFields();// 获得bean的所有属性

for (T elem : list) {// 开始迭代传入的list

Element child = root.addElement(GetElemName(bean));// 创建子元素

for (Field field : fields) {// 迭代属性并且赋值

int mod = field.getModifiers();

if (Modifier.isFinal(mod) || Modifier.isStatic(mod)

|| Modifier.isPublic(mod)) {

continue;

}

field.setAccessible(true);// 打破封装性

String attr_name = GetAttrName(bean, field);// 获取bean属性对应的xml文件中的名字

String attr_value = GetAttrValue(field, elem);// 获取此属性对应的值

// System.out.println(attr_name+"="+attr_value);

child.addElement(attr_name).setText(attr_value);// 创建属性并赋值

}

}

/*

* 这里就是把Parse的返回字串转化为了保存为文件而已

*/

FileOutputStream fos = null;

XMLWriter writer = null;

try {

fos = new FileOutputStream(path);

OutputFormat format = OutputFormat.createPrettyPrint();

format.setEncoding("UTF-8");

writer = new XMLWriter(fos, format);

writer.write(document);

writer.flush();

} catch (Exception e) {

e.printStackTrace();

} finally {

if (writer != null) {

try {

writer.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值