• [工具库]JOXMLBuilder工具类——一键把多个bean对象数据转换为XML格式数据


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

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

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

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

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

    本文转载,来自:http://www.cnblogs.com/tiantianbyconan/archive/2013/02/19/2917398.html

    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<String> includes = null; // 要包含的属性列表
     20     private List<String> excludes = null; // 要排除的属性列表
     21     
     22     /**
     23      * 默认构造方法。<br>
     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中每项属性信息的<b>包含</b>和<b>排除</b>。<br>
     38      * <ol>
     39      * <li>使用includes,不使用excludes:只生成在includes中的信息<br>
     40      * <li>不使用includes,使用excludes:只生成不在excludes中的信息<br>
     41      * <li>既使用includes,又使用exclude(不建议):<br>
     42      *  - 如果includes中和excludes中的信息不冲突,则生成不在excludes中的信息<br>
     43      *  - 如果includes中和excludes中的信息冲突(某个属性都出现在这两个数组中),则冲突部分的信息还是会生成<br>
     44      * <li>includes和excludes都不使用,则会把list中每项的所有属性信息都会生成在xml中
     45      * </ol>
     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 wangjie
    110      * @return 返回生成的xml字符串。
    111      * @throws Exception 如果List检验不通过,则抛出异常
    112      */
    113     public StringBuilder xmlBuild() throws Exception{
    114         //检验传入的List是否有效
    115         checkValidityList();
    116         //XML文件开始生成-------------------------
    117         result = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
    118         xmlSubBuild(list); // 递归生成
    119         return result;
    120     }
    121     /**
    122      * 生成xml可递归部分的子数据(根据某些对象组成的List来生成属性xml文件)。
    123      * @author wangjie
    124      * @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("</" + simpleName + "All>"); // 根标签结束
    140     }
    141     /**
    142      * 生成xml可递归部分的子子数据(根据某个对象来生成属性xml文件)。
    143      * @author wangjie
    144      * @param curObj 要生成xml文件的那个对象 
    145      * @param list curObj参数属于的那个List
    146      */
    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<Object> subList = new ArrayList<Object>(); 
    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("</" + fieldName + ">");
    218                 }
    219                 //*********************************************************
    220             } catch (Exception e) {
    221                 e.printStackTrace();
    222             }
    223             
    224         }
    225         result.append("</" + simpleName + ">");
    226     }
    227     
    228     /**
    229      * <ol>通过属性Field对象来获取getter方法的方法名。<br>
    230      * 如果是boolean或Boolean类型(正则表达式来判断):isBorrow-->isBorrow();isborrow-->isIsborrow();<br>
    231      * 否则:borrow-->getBorrow();
    232      * </ol>
    233      * @author wangjie
    234      * @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 wangjie
    257      * @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<Book> 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<Student> list = new ArrayList<Student>();
     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 <?xml version="1.0" encoding="utf-8"?>
     2 <StudentAll>
     3         <Student>
     4                 <name>hello</name>
     5                 <age>23</age>
     6                 <isBoy>true</isBoy>
     7                 <BookAll>
     8                         <Book>
     9                                 <name>book1</name>
    10                                 <author>author1</author>
    11                                 <number>123</number>
    12                                 <length>23.5</length>
    13                                 <width>18.0</width>
    14                                 <isBorrowed>true</isBorrowed>
    15                         </Book>
    16                         <Book>
    17                                 <name>book2</name>
    18                                 <author>author2</author>
    19                                 <number>43</number>
    20                                 <length>42.23</length>
    21                                 <width>30.57</width>
    22                                 <isBorrowed>false</isBorrowed>
    23                         </Book>
    24                 </BookAll>
    25         </Student>
    26 
    27         <Student>
    28                 <name>world</name>
    29                 <age>22</age>
    30                 <isBoy>false</isBoy>
    31                 <BookAll>
    32                          <Book>
    33                                 <name>book1</name>
    34                                 <author>author1</author>
    35                                 <number>123</number>
    36                                 <length>23.5</length>
    37                                 <width>18.0</width>
    38                                 <isBorrowed>true</isBorrowed>
    39                         </Book>
    40                         <Book>
    41                                 <name>book3</name>
    42                                 <author>author3</author>
    43                                 <number>875</number>
    44                                 <length>20.59</length>
    45                                 <width>15.08</width>
    46                                 <isBorrowed>false</isBorrowed>
    47                         </Book>
    48                         <Book>
    49                                 <name>book4</name>
    50                                 <author>author4</author>
    51                                 <number>165</number>
    52                                 <length>22.75</length>
    53                                 <width>19.61</width>
    54                                 <isBorrowed>true</isBorrowed>
    55                         </Book>
    56                 </BookAll>
    57         </Student>
    58 </StudentAll>
  • 相关阅读:
    P1410 子序列
    P1395 会议 (树形dp)
    P2580 于是他错误的点名开始了
    LC1127. 用户购买平台
    LC 1308. Running Total for Different Genders
    P1340 兽径管理 (最小生成树)
    P1330 封锁阳光大学 (二分图染色)
    CF1296F Berland Beauty (Tree, dfs/bfs, LCA)
    顺丰的Cookie条款
    服务器判断客户端的用户名和密码(token的身份验证)
  • 原文地址:https://www.cnblogs.com/tiantianbyconan/p/2917398.html
Copyright © 2020-2023  润新知