[工具库]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 ]

 

 

posted @ 2013-02-19 17:30  天天_byconan  阅读(3882)  评论(1编辑  收藏  举报