将List<T>生成XML文档(字串),将XML文档(字串)解析成List<T>,适用于任何对象的
2016-10-07 00:00
417 查看
很多刚开始涉猎web开发的猿友可能会遇到一个情况,就是将服务器端的数据传回前端,如果前端是浏览器的话是没有什么问题的,把服务器的各种对象属性通过OGNL或者JSTL等等很轻松的呈现出来。可如果前端是JavaSE开发的桌面应用或者Android应用,就比较麻烦了。
这时我们只能传回去一些Header或者Content,也就是头和字串,所以也就产生了把字串格式规划好,传回去然后按照一定的规则解析出来,得到需要的属性,而我们常用的无非是XML与JSON两种格式数据。
对于JSON与XML在性能与格式上各有优点,XMl格式统一,符合标准,安全,缺点就是格式复杂,前后端解析需要大量的代码,JSON的话格式简单,易于读写,但是相对XML通用性还不是特别强。
使用XML传输对象的时候,往往我们需要将一个对象的各种属性转化成字符串构建成一个XML,然后解析的时候再将XML文件或者字符串取出来,赋值给对象的属性,由此生成一个具有有效属性的对象。
而每个对象的属性必然是不同的,所以经常我们会为每个对象写一套解析方法,所以庞大的代码工作量就产生了,那么有没有简单一点的方法呢?我是这样做的,话不多说,先上效果图。
执行代码
结果
图截取不下来,在文件中或者浏览器格式是很好的,把输出结果给大家复制出来看
然后再将生成的xml字符串转回对象
结果(重写的toString方法)
这就是List与XML的正向逆向解析,如果是一个对象就将这个对象转换为List即可。
再测试一个Java对象
结果
这些自定义的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与这个模型拷贝过去即可。
希望能帮助大家。
如果有什么不对或者更好的建议,希望大家提出来,谢谢,因为是第一次写,不足之处多多指教。
模型源码,使用方式以及思路注释里都有
这时我们只能传回去一些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); }
结果
图截取不下来,在文件中或者浏览器格式是很好的,把输出结果给大家复制出来看
<?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(); } } } } }
相关文章推荐
- 用Pull解析将xml转换成List<Object>对象
- 读取xml文件转成List<T>对象的两种方法
- (转) 读取xml文件转成List<T>对象的两种方法
- Dom4J解析xml文件动态转换为List<Bean>或者Map集合
- 读取导入excel表txt文档,并存储到List<E>对象中
- 读取xml文件转成List<T>对象的两种方法
- 取xml文件转成List<T>对象的两种方法
- 前台的js对象数组传到后台处理。在前台把js对象数组转化为json字符串,在后台把json字符串解析为List<>
- ios XML,JSON,数组解析并转换成NSMutableArray(List<class>)
- 读取xml文件转成List<T>对象的两种方法(附源码)
- Dom4J解析xml文件动态转换为List<Bean>或者Map集合
- 读取xml文件转成List<T>对象的两种方法(附源码)
- net.sf.ezmorph.bean.MorphDynaBean cannotbe cast to xxx 关于JSON对象解析List<XXX>在调用时出错问题
- Dom4j解析XML文本,遍历指定节点下的节点内容和属性,并存入List<Map<String,Object>
- 对 List<map>内对象进行排序
- GridView绑定List<T>时要把自动生成行
- dom4j生成XML文档及解析
- DSOFramer控件文档上传到服务器处理页面后,怎么解析数据 <转>
- 如何判断对象包含List<T>中的类型
- android 解析webservice List<Object> 填充下拉列表