将List生成XML文档(字串),将XML文档(字串)解析成List,适用于任何对象

      转自:https://my.oschina.net/u/2938193/blog/754983

  对于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);
	}

结果:

<?xml version="1.0" encoding="UTF-8"?>
<_persons><_person><person_id>2</person_id><person_username>abc</person_username><person_password>123</person_password><person_name>xiao南瓜</person_name><person_bound>!@#</person_bound></_person></_persons>

然后再将生成的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<Person> persons = ParseXML(sXml, Person.class);
		Person person2 = persons.get(0);
		System.out.println(person);
		System.out.println(person2);
	}

结果(重写的toString方法):

这就是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<Location> locations=ParseXML(sXml, Location.class);
		Location location2=locations.get(0);
		System.out.println(location);
		System.out.println(location2);
	}

结果:

这些自定义的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 <T> 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 <T> 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 <T> String ParseList(List<T> 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 <T> List<T> ParseXML(String content, Class<?> bean) {
		List<T> elements = new ArrayList<T>();// 构建一个空的list
		try {
			Document document = DocumentHelper.parseText(content);// 根据传入的content获取document
			Element rootElement = document.getRootElement();// 获取根元素

			Field[] fields = bean.getDeclaredFields();// 获取此bean的所有属性
			// 迭代根元素下所有的子元素
			for (Iterator<Element> 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 <T> List<T> ReadListByFile(String path, Class<?> bean) {
		List<T> elements = new ArrayList<T>();// 构建一个空的list
		try {
			SAXReader saxReader = new SAXReader();
			Document document = saxReader.read(new File(path));
			Element rootElement = document.getRootElement();// 获取根元素

			Field[] fields = bean.getDeclaredFields();// 获取此bean的所有属性
			// 迭代根元素下所有的子元素
			for (Iterator<Element> 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 <T> void WriteFileByList(String path, List<T> 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 <T> void AddElementsByList(String path, List<T> 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();
				}
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_38676276/article/details/86649742