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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM