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


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

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

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

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

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

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

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

    源码如下:

    View Code
      1 package com.wangjie.extrautil.jojsonbuilder;
      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-14 上午10:49:59
     15  */
     16 public class JOJSONBuilder {
     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 JOJSONBuilder() {
     27         
     28     }
     29     /**
     30      * 此构造方法会把list中每项的所有属性信息都会生成在json中。
     31      * @param list 所要生成Json的List数据源
     32      */
     33     public JOJSONBuilder(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中每项的所有属性信息都会生成在json中
     45      * </ol>
     46      * @param list 所要生成Json的List数据源。
     47      * @param includes 所要包含的属性名称数组。
     48      * @param excludes 所要排除的属性名称数组。
     49      */
     50     public JOJSONBuilder(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      * 获得正在进行生成json文件的信息来源List。
     57      * @author wangjie
     58      * @return 返回正在进行生成json文件的信息来源List
     59      */
     60     public List<?> getList() {
     61         return list;
     62     }
     63     /**
     64      * 可使用此方法来传入、替换JOJSONBuilder对象中的List对象。
     65      * @author wangjie
     66      * @param list 所要生成Json的List数据源。
     67      * @return 返回当前JOJSONBuilder对象
     68      */
     69     public JOJSONBuilder setList(List<?> list) {
     70         this.list = list;
     71         return this;
     72     }
     73     /**
     74      * 设置包含的属性信息。
     75      * @author wangjie
     76      * @param incFieldName 要包含的属性名
     77      * @return 返回当前JOJSONBuilder对象
     78      */
     79     public JOJSONBuilder 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 返回当前JOJSONBuilder对象
     88      */
     89     public JOJSONBuilder 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      * @param clazz 要获取的属性的类的Class对象。
     97      * @return 返回该Class对象的所有属性。
     98      */
     99     public Field[] getFields(Class<?> clazz) {
    100         Field[] fields = clazz.getDeclaredFields();
    101         System.out.print("fields of the class that named " + clazz.getName() + ": ");
    102         for(Field field : fields){
    103             System.out.print(field.getName() + ", ");
    104         }
    105         System.out.println();
    106         return fields;
    107     }
    108     
    109     /**
    110      * 根据list中的对象来生成对应的json文件。
    111      * @author wangjie
    112      * @return 返回生成的Json字符串。
    113      * @throws Exception 如果List检验不通过,则抛出异常。
    114      */
    115     public StringBuilder jsonBuild() throws Exception{
    116         //检验传入的List是否有效
    117         checkValidityList();
    118         //json文件开始生成-------------------------
    119         result = new StringBuilder();
    120         jsonSubBuild(list); // 递归生成
    121         return result;
    122     }
    123     /**
    124      * 生成json可递归部分的子数据(根据某些对象组成的List来生成属性json文件)
    125      * @author wangjie
    126      * @param list 
    127      */
    128     private void jsonSubBuild(List<?> list){
    129 //        Class<?> clazz = list.get(0).getClass(); // 获取对应的Class对象
    130         Object curObj = null; // 每次循环当前的类对象(资源)
    131         int listLength = list.size(); // 类对象个数
    132 //        String simpleName = clazz.getSimpleName(); // 获取类名(不含包名)
    133         
    134         result.append("["); // 根标签开始
    135         
    136         for(int i = 0; i < listLength; i++){
    137             if(i != 0){
    138                 result.append(",");
    139             }
    140             curObj = list.get(i);
    141             jsonSubSubBuild(curObj, list); // 子数据递归
    142         }
    143         
    144         result.append("]"); // 根标签结束
    145     }
    146     /**
    147      * 生成json可递归部分的子子数据(根据某个对象来生成属性json文件)
    148      * @author wangjie
    149      * @param curObj 要生成json文件的那个对象 
    150      * @param list curObj参数属于的那个List
    151      */
    152     private void jsonSubSubBuild(Object curObj, List<?> list){
    153         String fieldName = ""; // 每次要调用的属性名
    154         String methodName = ""; // 每次要调用的方法名
    155         Method method = null;; // 每次要调用的方法
    156         Object value = ""; // 每次要获得的属性值(子标签)
    157         
    158         Class<?> clazz = curObj.getClass();
    159         Field[] fields = getFields(clazz); // 获得对应类型的所有变量
    160         int fieldsLength = fields.length; // 类对象的属性数量
    161         
    162         result.append("{");
    163         int offset = 0; // 包含的第一个属性偏移量
    164         int temp = 0;
    165         for(int j = 0; j < fieldsLength; j++){
    166             fieldName = fields[j].getName(); // 获取对应属性名
    167             
    168             if(list == this.list){ // 只在最外层的类的属性中进行排除包含
    169                 // 使用includes,不使用excludes:只生成在includes中的信息
    170                 if(null != includes && null == excludes){
    171                     if(!includes.contains(fieldName)){
    172                         continue;
    173                     }
    174                 }
    175                 
    176                 //不使用includes,使用excludes:只生成不在excludes中的信息
    177                 if(null == includes && null != excludes){ // 只使用了不包含
    178                     if(excludes.contains(fieldName)){
    179                         continue;
    180                     }
    181                 }
    182                 
    183                 //既使用includes,又使用exclude(不建议):
    184                 //- 如果includes中和excludes中的信息不冲突,则生成不在excludes中的信息
    185                 //- 如果includes中和excludes中的信息冲突(某个属性都出现在这两个数组中),则冲突部分的信息还是会生成
    186                 if(null != includes && null != excludes){ // 既使用了包含,又使用了不包含
    187                     if(!includes.contains(fieldName) && excludes.contains(fieldName)){
    188                         continue;
    189                     }
    190                 }
    191                 // 记录第一个包含的属性的索引
    192                 if(0 == temp){
    193                     offset = j;
    194                     temp++;
    195                 }
    196 //                offset = 0 == temp++ ? j : 0;
    197             }
    198             
    199             methodName = getGetterMethodNameByFieldName(fields[j]);
    200             try {
    201                 method = clazz.getDeclaredMethod(methodName, new Class[]{});
    202                 method.setAccessible(true);
    203                 value = method.invoke(curObj, new Object[]{});
    204                 //*********************************************************
    205                 if(j != offset){ // 第一个属性前面不加","
    206                     result.append(",");
    207                 }
    208                 result.append("'" + fieldName + "':");
    209                 if(fields[j].getType() == List.class){ // 如果属性是List类型
    210                     List<?> subList = (List<?>)value;
    211                     jsonSubBuild(subList); // 子数据递归
    212                 }else if(fields[j].getType() == Set.class){ // 如果属性是Set类型的
    213                     Set<?> subSet = (Set<?>)value;
    214                     Iterator<?> iter = subSet.iterator();
    215                     List<Object> subList = new ArrayList<Object>(); 
    216                     while(iter.hasNext()){
    217                         subList.add(iter.next());
    218                     }
    219                     jsonSubBuild(subList); // 子数据递归
    220                 }
    221                 // 如果ClassLoader不是null表示该类不是启动类加载器加载的,不是Java API的类,是自己写的java类
    222                 else if(null != fields[j].getType().getClassLoader()){ 
    223                     jsonSubSubBuild(value, null); // 子子数据递归
    224                 }
    225                 else{ // 其它类型都认为是普通文本类型
    226                     // 添加子元素(类属性)标签
    227                     if(value.getClass() == String.class){
    228                         result.append("'" + value + "'");
    229                     }else{
    230                         result.append(value.toString());
    231                     }
    232                     
    233                 }
    234                 
    235                 //*********************************************************
    236             } catch (Exception e) {
    237                 e.printStackTrace();
    238             }
    239             
    240         }
    241         result.append("}");
    242     }
    243     
    244     /**
    245      * <ol>通过属性Field对象来获取getter方法的方法名。<br>
    246      * 如果是boolean或Boolean类型(正则表达式来判断):isBorrow-->isBorrow();isborrow-->isIsborrow();<br>
    247      * 否则:borrow-->getBorrow();
    248      * </ol>
    249      * @author wangjie
    250      * @param field 要生成getter方法的对应属性对象。
    251      * @return 返回getter方法的方法名。
    252      */
    253     private String getGetterMethodNameByFieldName(Field field){
    254         String methodName = null;
    255         String fieldName = field.getName();
    256         // 解析属性对应的getter方法名
    257         // 判断是否是boolean或Boolean类型:isBorrow-->isBorrow();isborrow-->isIsborrow()
    258         if(field.getType() == boolean.class || field.getType() == Boolean.class){
    259             if(fieldName.matches("^is[A-Z].*")){
    260                 methodName = fieldName;
    261             }else{
    262                 methodName = "is" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    263             }
    264         }else{
    265             methodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    266         }
    267         return methodName;
    268     }
    269     
    270     /**
    271      * 检验传入的List的合法性(List是不是为null、长度是不是为0、是不是每项都是同一个类型)
    272      * @author wangjie
    273      * @throws Exception 如果List为null, 或者长度为, 或者每项不是同一个类型, 抛出异常
    274      */
    275     private void checkValidityList() throws Exception{
    276         if(null == list){
    277             throw new Exception("请保证传入的List不为null");
    278         }
    279         int size = list.size();
    280         if(list.size() == 0){
    281             throw new Exception("请保证传入的List长度不为0");
    282         }
    283         for(int i = 1; i < size; i++){
    284             if(list.get(0).getClass() != list.get(i).getClass()){
    285                 throw new Exception("请保证传入的List每项都是同一个类型");
    286             }
    287         }
    288         
    289     }
    290     
    291     
    292     
    293 }

    使用方法如下:

    例如:
    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转换为Json:

    List<Student> list = new ArrayList<Student>();
    
    //构建几个Student对象,放入list中
    //……
    
    //完整数据版(不使用includes和excludes)
    JOJSONBuilder jsonBuilder = new JOJSONBuilder(list);
    String content = jsonBuilder.jsonBuild().toString();
    
    //或者使用包括/排除:
    JOJSONBuilder jsonBuilder = new JOJSONBuilder(list, new String[]{"name", "age"}, null);
    jsonBuilder.jsonBuild().toString();
    
    //或者使用方法链风格:
    new JOJSONBuilder().setExcludes("name", "age").jsonBuild().toString();

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

     1 [
     2         {
     3                 'name':'hello',
     4                 'age':23,
     5                 'isBoy':true,
     6                 'books':[
     7                                         {
     8                                                 'name':'book1',
     9                                                 'author':'author1',
    10                                                 'number':123,
    11                                                 'length':23.5,
    12                                                 'width':18.0,
    13                                                 'isBorrowed':true
    14                                         },
    15                                         {
    16                                                 'name':'book2',
    17                                                 'author':'author2',
    18                                                 'number':43,
    19                                                 'length':42.23,
    20                                                 'width':30.57,
    21                                                 'isBorrowed':false
    22                                         }
    23                                 ]
    24         },
    25 
    26         {
    27                 'name':'world',
    28                 'age':22,
    29                 'isBoy':false,
    30                 'books':[
    31                                         {
    32                                                 'name':'book1',
    33                                                 'author':'author1',
    34                                                 'number':123,
    35                                                 'length':23.5,
    36                                                 'width':18.0,
    37                                                 'isBorrowed':true
    38                                         },
    39                                         {
    40                                                 'name':'book3',
    41                                                 'author':'author3',
    42                                                 'number':875,
    43                                                 'length':20.59,
    44                                                 'width':15.08,
    45                                                 'isBorrowed':false
    46                                         },
    47                                         {
    48                                                 'name':'book4',
    49                                                 'author':'author4',
    50                                                 'number':165,
    51                                                 'length':22.75,
    52                                                 'width':19.61,
    53                                                 'isBorrowed':true
    54                                         }
    55                                 ]
    56         }
    57 ]
  • 相关阅读:
    Oracle重建表索引及手工收集统计信息
    VirtualBox虚拟机安装MSDOS和MINIX2.0.0双系统
    odp.net以及oracle oledb安装
    Oralce常用维护命令
    Sales_item
    IBM MQ Reason 2538(MQRC_HOST_NOT_AVAILABLE) 错误原因一例
    Unable to create the store directory. (Exception from HRESULT: 0x80131468)
    WMS函数组:13.WMS入库BAPI
    WMS函数组:12.批量入库物料移动凭证
    WMS函数组:11.交货单取金额
  • 原文地址:https://www.cnblogs.com/tiantianbyconan/p/2917433.html
Copyright © 2020-2023  润新知