博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[工具库]JOXMLBuilder工具类——一键把多个bean对象数据转换为XML格式数据
阅读量:6090 次
发布时间:2019-06-20

本文共 14632 字,大约阅读时间需要 48 分钟。

本人大四即将毕业的准程序员(JavaSE、JavaEE、android等)一枚,小项目也做过一点,于是乎一时兴起就写了一些工具。

我会在本博客中陆续发布一些平时可能会用到的工具。

代码质量可能不是很好,大家多担待!

代码或者思路有不妥之处,还希望大牛们能不吝赐教哈!

 

以下代码为本人原创,转载请注明:

本文转载,来自:

 

JOXMLBuilder工具类:一键把多个域对象数据转换为XML格式数据,方便用于数据的传输和交互。功能类似于通过Gson来生成Json数据。

源码如下:

View Code
1 package com.wangjie.extrautil.joxmlbuilder;  2   3 import java.lang.reflect.Field;  4 import java.lang.reflect.Method;  5 import java.util.ArrayList;  6 import java.util.Arrays;  7 import java.util.Iterator;  8 import java.util.List;  9 import java.util.Set; 10  11 /** 12  *  13  * @author wangjie 14  * @version 创建时间:2013-2-3 下午3:49:59 15  */ 16 public class JOXMLBuilder { 17     private List
list; // 传入的List数据 18 private StringBuilder result = null; 19 private List
includes = null; // 要包含的属性列表 20 private List
excludes = null; // 要排除的属性列表 21 22 /** 23 * 默认构造方法。
24 * 使用此默认的构造方法之后必须要调用setList()传入List 25 */ 26 public JOXMLBuilder() { 27 28 } 29 /** 30 * 此构造方法会把list中每项的所有属性信息都会生成在xml中。 31 * @param list 所要生成xml的List数据源。 32 */ 33 public JOXMLBuilder(List
list) { 34 this.list = list; 35 } 36 /** 37 * 此构造方法提供list中每项属性信息的
包含
排除
38 *
    39 *
  1. 使用includes,不使用excludes:只生成在includes中的信息
    40 *
  2. 不使用includes,使用excludes:只生成不在excludes中的信息
    41 *
  3. 既使用includes,又使用exclude(不建议):
    42 * - 如果includes中和excludes中的信息不冲突,则生成不在excludes中的信息
    43 * - 如果includes中和excludes中的信息冲突(某个属性都出现在这两个数组中),则冲突部分的信息还是会生成
    44 *
  4. includes和excludes都不使用,则会把list中每项的所有属性信息都会生成在xml中 45 *
46 * @param list 所要生成Json的List数据源。 47 * @param includes 所要包含的属性名称数组。 48 * @param excludes 所要排除的属性名称数组。 49 */ 50 public JOXMLBuilder(List
list, String[] includes, String[] excludes) { 51 this.list = list; 52 this.includes = null == includes || includes.length == 0 ? null : Arrays.asList(includes); 53 this.excludes = null == excludes || excludes.length == 0 ? null : Arrays.asList(excludes); 54 } 55 /** 56 * 返回正在进行生成xml文件的信息来源List。 57 * @author wangjie 58 * @return 返回正在进行生成xml文件的信息来源List。 59 */ 60 public List
getList() { 61 return list; 62 } 63 /** 64 * 可使用此方法来传入、替换JOXMLBuilder对象中的List对象。 65 * @author wangjie 66 * @param list 所要生成xml的List数据源。 67 * @return 返回当前JOXMLBuilder对象 68 */ 69 public JOXMLBuilder setList(List
list) { 70 this.list = list; 71 return this; 72 } 73 /** 74 * 设置包含的属性信息。 75 * @author wangjie 76 * @param incFieldName 要包含的属性名 77 * @return 返回当前JOXMLBuilder对象 78 */ 79 public JOXMLBuilder setIncludes(String... incFieldName) { 80 this.includes = null == incFieldName || incFieldName.length == 0 ? null : Arrays.asList(incFieldName); 81 return this; 82 } 83 /** 84 * 设置排除的属性信息。 85 * @author wangjie 86 * @param excFieldName 要排除的属性名 87 * @return 返回当前JOXMLBuilder对象 88 */ 89 public JOXMLBuilder setExcludes(String... excFieldName) { 90 this.excludes = null == excFieldName || excFieldName.length == 0 ? null : Arrays.asList(excFieldName); 91 return this; 92 } 93 /** 94 * 获得指定Class类型的所有属性,并打印在控制台上。 95 * @author wangjie 96 */ 97 public Field[] getFields(Class
clazz) { 98 Field[] fields = clazz.getDeclaredFields(); 99 System.out.print("fields of the class that named " + clazz.getName() + ": ");100 for(Field field : fields){101 System.out.print(field.getName() + ", ");102 }103 System.out.println();104 return fields;105 }106 107 /**108 * 根据list中的对象来生成对应的xml文件。109 * @author wangjie110 * @return 返回生成的xml字符串。111 * @throws Exception 如果List检验不通过,则抛出异常112 */113 public StringBuilder xmlBuild() throws Exception{114 //检验传入的List是否有效115 checkValidityList();116 //XML文件开始生成-------------------------117 result = new StringBuilder("
");118 xmlSubBuild(list); // 递归生成119 return result;120 }121 /**122 * 生成xml可递归部分的子数据(根据某些对象组成的List来生成属性xml文件)。123 * @author wangjie124 * @param list 125 */126 private void xmlSubBuild(List
list){127 Class
clazz = list.get(0).getClass(); // 获取对应的Class对象128 Object curObj = null; // 每次循环当前的类对象(资源)129 int listLength = list.size(); // 类对象个数130 String simpleName = clazz.getSimpleName(); // 获取类名(不含包名)131 132 result.append("<" + simpleName + "All>"); // 根标签开始133 134 for(int i = 0; i < listLength; i++){135 curObj = list.get(i);136 xmlSubSubBuild(curObj, list); // 子数据递归137 }138 139 result.append("
"); // 根标签结束140 }141 /**142 * 生成xml可递归部分的子子数据(根据某个对象来生成属性xml文件)。143 * @author wangjie144 * @param curObj 要生成xml文件的那个对象 145 * @param list curObj参数属于的那个List146 */147 private void xmlSubSubBuild(Object curObj, List
list){148 String fieldName = ""; // 每次要调用的属性名149 String methodName = ""; // 每次要调用的方法名150 Method method = null;; // 每次要调用的方法151 Object value = ""; // 每次要获得的属性值(子标签)152 153 Class
clazz = curObj.getClass();154 Field[] fields = getFields(clazz); // 获得对应类型的所有变量155 int fieldsLength = fields.length; // 类对象的属性数量156 157 String simpleName = clazz.getSimpleName(); // 获取类名(不含包名)158 159 result.append("<" + simpleName + ">");160 161 162 for(int j = 0; j < fieldsLength; j++){163 fieldName = fields[j].getName(); // 获取对应属性名164 165 if(list == this.list){ // 只在最外层的类的属性中进行排除包含166 // 使用includes,不使用excludes:只生成在includes中的信息167 if(null != includes && null == excludes){168 if(!includes.contains(fieldName)){169 continue;170 }171 }172 173 //不使用includes,使用excludes:只生成不在excludes中的信息174 if(null == includes && null != excludes){ // 只使用了不包含175 if(excludes.contains(fieldName)){176 continue;177 }178 }179 180 //既使用includes,又使用exclude(不建议):181 //- 如果includes中和excludes中的信息不冲突,则生成不在excludes中的信息182 //- 如果includes中和excludes中的信息冲突(某个属性都出现在这两个数组中),则冲突部分的信息还是会生成183 if(null != includes && null != excludes){ // 既使用了包含,又使用了不包含184 if(!includes.contains(fieldName) && excludes.contains(fieldName)){185 continue;186 }187 }188 }189 190 methodName = getGetterMethodNameByFieldName(fields[j]);191 try {192 method = clazz.getDeclaredMethod(methodName, new Class[]{});193 method.setAccessible(true);194 value = method.invoke(curObj, new Object[]{});195 //*********************************************************196 if(fields[j].getType() == List.class){ // 如果属性是List类型197 List
subList = (List
)value;198 xmlSubBuild(subList); // 子数据递归199 }else if(fields[j].getType() == Set.class){ // 如果属性是Set类型的200 Set
subSet = (Set
)value;201 Iterator
iter = subSet.iterator();202 List
subList = new ArrayList(); 203 while(iter.hasNext()){204 subList.add(iter.next());205 }206 xmlSubBuild(subList); // 子数据递归207 }208 // 如果ClassLoader不是null表示该类不是启动类加载器加载的,不是Java API的类,是自己写的java类209 else if(null != fields[j].getType().getClassLoader()){ 210 xmlSubSubBuild(value, null); // 子子数据递归211 }212 else{ // 其它类型都认为是普通文本类型213 value = value.toString();214 // 添加子元素(类属性)标签215 result.append("<" + fieldName + ">")216 .append(value)217 .append("
");218 }219 //*********************************************************220 } catch (Exception e) {221 e.printStackTrace();222 }223 224 }225 result.append("
");226 }227 228 /**229 *
    通过属性Field对象来获取getter方法的方法名。
    230 * 如果是boolean或Boolean类型(正则表达式来判断):isBorrow-->isBorrow();isborrow-->isIsborrow();
    231 * 否则:borrow-->getBorrow();232 *
233 * @author wangjie234 * @param field 要生成getter方法的对应属性对象。235 * @return 返回getter方法的方法名。236 */237 private String getGetterMethodNameByFieldName(Field field){238 String methodName = null;239 String fieldName = field.getName();240 // 解析属性对应的getter方法名241 // 判断是否是boolean或Boolean类型:isBorrow-->isBorrow();isborrow-->isIsborrow()242 if(field.getType() == boolean.class || field.getType() == Boolean.class){243 if(fieldName.matches("^is[A-Z].*")){244 methodName = fieldName;245 }else{246 methodName = "is" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);247 }248 }else{249 methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);250 }251 return methodName;252 }253 254 /**255 * 检验传入的List的合法性(List是不是为null、长度是不是为0、是不是每项都是同一个类型)。256 * @author wangjie257 * @throws Exception 如果List为null, 或者长度为, 或者每项不是同一个类型, 抛出异常258 */259 private void checkValidityList() throws Exception{260 if(null == list){261 throw new Exception("请保证传入的List不为null");262 }263 int size = list.size();264 if(list.size() == 0){265 throw new Exception("请保证传入的List长度不为0");266 }267 for(int i = 1; i < size; i++){268 if(list.get(0).getClass() != list.get(i).getClass()){269 throw new Exception("请保证传入的List每项都是同一个类型");270 }271 }272 273 }274 275 276 }

 

使用方法如下:

例如:
Student类(该类有属性name,age,isBoy,books等属性;其中books属性是一个List,存放Book对象):

1 private String name;2 private int age;3 private boolean isBoy;4 private List
books;5 //并实现getter和setter方法;

 

Book类(该类有属性name,author,number,length,width,isBorrowed等属性):

1 private String name;2 private String author;3 private int number;4 private float length;5 private float width;6 private boolean isBorrowed;7 //并实现getter和setter方法;

 

现在有一个List<Student>类型的数据,通过以下代码把该List转换为xml:

1 List
list = new ArrayList
(); 2 3 //构建几个Student对象,放入list中 4 //…… 5 6 //完整数据版(不使用includes和excludes) 7 JOXMLBuilder jOXMLBuilder = new JOXMLBuilder(list); 8 jOXMLBuilder.xmlBuild().toString(); 9 10 //或者使用包括/排除:11 JOXMLBuilder jOXMLBuilder = new JOXMLBuilder(list, new String[]{"name", "age"}, null);12 jOXMLBuilder.xmlBuild().toString();13 14 //或者使用方法链风格:15 new JOXMLBuilder().setExcludes("name", "age").xmlBuild().toString();

 

转换之后的xml(完整数据版(不使用includes和excludes)):

1 
2
3
4
hello
5
23
6
true
7
8
9
book1
10
author1
11
123
12
23.5
13
18.0
14
true
15
16
17
book2
18
author2
19
43
20
42.23
21
30.57
22
false
23
24
25
26 27
28
world
29
22
30
false
31
32
33
book1
34
author1
35
123
36
23.5
37
18.0
38
true
39
40
41
book3
42
author3
43
875
44
20.59
45
15.08
46
false
47
48
49
book4
50
author4
51
165
52
22.75
53
19.61
54
true
55
56
57
58

 

 

你可能感兴趣的文章
DIRECTSHOW在VS2005中PVOID64问题和配置问题
查看>>
MapReduce的模式,算法以及用例
查看>>
《Advanced Linux Programming》读书笔记(1)
查看>>
zabbix agent item
查看>>
一步一步学习SignalR进行实时通信_7_非代理
查看>>
字符设备与块设备的区别
查看>>
为什么我弃用GNOME转向KDE(2)
查看>>
Redis学习记录初篇
查看>>
爬虫案例若干-爬取CSDN博文,糗事百科段子以及淘宝的图片
查看>>
Web实时通信技术
查看>>
第三章 计算机及服务器硬件组成结合企业运维场景 总结
查看>>
IntelliJ IDEA解决Tomcal启动报错
查看>>
默认虚拟主机设置
查看>>
php中的短标签 太坑人了
查看>>
[译] 可维护的 ETL:使管道更容易支持和扩展的技巧
查看>>
### 继承 ###
查看>>
数组扩展方法之求和
查看>>
astah-professional-7_2_0安装
查看>>
函数是对象-有属性有方法
查看>>
uva 10107 - What is the Median?
查看>>