JSON和对象之前的相互转换

  1 package com.jxjson.com;
  2 
  3 import android.util.Log;
  4 
  5 import org.json.JSONArray;
  6 import org.json.JSONException;
  7 import org.json.JSONObject;
  8 
  9 import java.lang.reflect.Constructor;
 10 import java.lang.reflect.Field;
 11 import java.lang.reflect.Type;
 12 import java.util.ArrayList;
 13 import java.util.Iterator;
 14 import java.util.List;
 15 
 16 public class JsonTool {
 17 
 18     private static boolean DEBUG = false;
 19 
 20     /**
 21      * 将JSON字符串封装到对象
 22      *
 23      * @param jsonStr 待封装的JSON字符串
 24      * @param clazz 待封装的实例字节码
 25      * @return T: 封装JSON数据的对象
 26      * @version 1.0
 27      */
 28     public static <T> T toBean(String jsonStr, Class<T> clazz) {
 29         try {
 30             JSONObject job = new JSONObject(jsonStr);
 31             return parseObject(job, clazz, null);
 32         } catch (JSONException e) {
 33             e.printStackTrace();
 34         }
 35         return null;
 36     }
 37 
 38     /**
 39      * 将 对象编码为 JSON格式
 40      *
 41      * @param t 待封装的对象
 42      * @return String: 封装后JSONObject String格式
 43      * @version 1.0
 44      */
 45     public static <T> String toJson(T t) {
 46         if (t == null) {
 47             return "{}";
 48         }
 49         return objectToJson(t);
 50     }
 51 
 52     /**
 53      * 由JSON字符串生成Bean对象
 54      *
 55      * @param jsonStr
 56      * @param className 待生成Bean对象的名称
 57      * @return String:
 58      * @version 1.0
 59      */
 60     public static String createBean(String jsonStr, String className) {
 61         try {
 62             JSONObject job = new JSONObject(jsonStr);
 63             return createObject(job, className, 0);
 64         } catch (JSONException e) {
 65             e.printStackTrace();
 66         }
 67         return "";
 68     }
 69 
 70     /**
 71      * JSONObject 封装到 对象实例
 72      *
 73      * @param job 待封装的JSONObject
 74      * @param c 待封装的实例对象class
 75      * @param v    待封装实例的外部类实例对象</br>只有内部类存在,外部类时传递null
 76      * @return T:封装数据的实例对象
 77      * @version 1.0
 78      * @date 2015-10-9
 79      */
 80     @SuppressWarnings("unchecked")
 81     private static <T, V> T parseObject(JSONObject job, Class<T> c, V v) {
 82         T t = null;
 83         try {
 84             if(null == v) {
 85                 t = c.newInstance();
 86             } else {
 87                 Constructor<?> constructor = c.getDeclaredConstructors()[0];
 88                 constructor.setAccessible(true);
 89                 t = (T) constructor.newInstance(v);
 90             }
 91         } catch (IllegalArgumentException e) {
 92             e.printStackTrace();
 93             Log.e(JsonTool.class.getSimpleName(),
 94                     c.toString() + " should provide a default constructor " +
 95                             "(a public constructor with no arguments)");
 96         } catch (Exception e) {
 97             if(DEBUG)
 98                 e.printStackTrace();
 99         }
100 
101         Field[] fields = c.getDeclaredFields();
102         for (Field field : fields) {
103             field.setAccessible(true);
104             Class<?> type = field.getType();
105             String name = field.getName();
106 
107             // if the object don`t has a mapping for name, then continue
108             if(!job.has(name)) continue;
109 
110             String typeName = type.getName();
111             if(typeName.equals("java.lang.String")) {
112                 try {
113                     String value = job.getString(name);
114                     if (value != null && value.equals("null")) {
115                         value = "";
116                     }
117                     field.set(t, value);
118                 } catch (Exception e) {
119                     if(DEBUG)
120                         e.printStackTrace();
121                     try {
122                         field.set(t, "");
123                     } catch (Exception e1) {
124                         if(DEBUG)
125                             e1.printStackTrace();
126                     }
127                 }
128             } else if(typeName.equals("int") ||
129                     typeName.equals("java.lang.Integer")) {
130                 try {
131                     field.set(t, job.getInt(name));
132                 } catch (Exception e) {
133                     if(DEBUG)
134                         e.printStackTrace();
135                 }
136             } else if(typeName.equals("boolean") ||
137                     typeName.equals("java.lang.Boolean")) {
138                 try {
139                     field.set(t, job.getBoolean(name));
140                 } catch (Exception e) {
141                     if(DEBUG)
142                         e.printStackTrace();
143                 }
144             } else if(typeName.equals("float") ||
145                     typeName.equals("java.lang.Float")) {
146                 try {
147                     field.set(t, Float.valueOf(job.getString(name)));
148                 } catch (Exception e) {
149                     if(DEBUG)
150                         e.printStackTrace();
151                 }
152             } else if(typeName.equals("double") ||
153                     typeName.equals("java.lang.Double")) {
154                 try {
155                     field.set(t, job.getDouble(name));
156                 } catch (Exception e) {
157                     if(DEBUG)
158                         e.printStackTrace();
159                 }
160             } else if(typeName.equals("long") ||
161                     typeName.equals("java.lang.Long")) {
162                 try {
163                     field.set(t, job.getLong(name));
164                 } catch (Exception e) {
165                     if(DEBUG)
166                         e.printStackTrace();
167                 }
168             } else if(typeName.equals("java.util.List") ||
169                     typeName.equals("java.util.ArrayList")){
170                 try {
171                     Object obj = job.get(name);
172                     Type genericType = field.getGenericType();
173                     String className = genericType.toString().replace("<", "")
174                             .replace(type.getName(), "").replace(">", "");
175                     Class<?> clazz = Class.forName(className);
176                     if(obj instanceof JSONArray) {
177                         ArrayList<?> objList = parseArray((JSONArray)obj, clazz, t);
178                         field.set(t, objList);
179                     }
180                 } catch (Exception e) {
181                     if(DEBUG)
182                         e.printStackTrace();
183                 }
184             } else {
185                 try {
186                     Object obj = job.get(name);
187                     Class<?> clazz = Class.forName(typeName);
188                     if(obj instanceof JSONObject) {
189                         Object parseJson = parseObject((JSONObject)obj, clazz, t);
190                         field.set(t, parseJson);
191                     }
192                 } catch (Exception e) {
193                     if(DEBUG)
194                         e.printStackTrace();
195                 }
196 
197             }
198         }
199 
200         return t;
201     }
202 
203     /**
204      * 将 JSONArray 封装到 ArrayList 对象
205      *
206      * @param array 待封装的JSONArray
207      * @param c 待封装实体字节码
208      * @param v 待封装实例的外部类实例对象</br>只有内部类存在,外部类时传递null
209      * @return ArrayList<T>: 封装后的实体集合
210      * @version 1.0
211      * @date 2015-10-8
212      */
213     @SuppressWarnings("unchecked")
214     private static <T, V> ArrayList<T> parseArray(JSONArray array, Class<T> c, V v) {
215         ArrayList<T> list = new ArrayList<T>(array.length());
216         try {
217             for (int i = 0; i < array.length(); i++) {
218                 if(array.get(i) instanceof JSONObject) {
219                     T t = parseObject(array.getJSONObject(i), c, v);
220                     list.add(t);
221                 } else {
222                     list.add((T) array.get(i));
223                 }
224 
225             }
226         } catch (Exception e) {
227             if(DEBUG)
228                 e.printStackTrace();
229         }
230         return list;
231     }
232 
233     /**
234      * 将 对象编码为 JSON格式
235      *
236      * @param t 待封装的对象
237      * @return String: 封装后JSONObject String格式
238      * @version 1.0
239      * @date 2015-10-11
240      */
241     private static <T> String objectToJson(T t) {
242 
243         Field[] fields = t.getClass().getDeclaredFields();
244         StringBuilder sb = new StringBuilder(fields.length << 4);
245         sb.append("{");
246 
247         for (Field field : fields) {
248             field.setAccessible(true);
249             Class<?> type = field.getType();
250             String name = field.getName();
251 
252             // 'this$Number' 是内部类的外部类引用(指针)字段
253             if(name.contains("this$")) continue;
254 
255             String typeName = type.getName();
256             if(typeName.equals("java.lang.String")) {
257                 try {
258                     sb.append("\""+name+"\":");
259                     sb.append(stringToJson((String)field.get(t)));
260                     sb.append(",");
261                 } catch (Exception e) {
262                     if(DEBUG)
263                         e.printStackTrace();
264                 }
265             } else if(typeName.equals("boolean") ||
266                     typeName.equals("java.lang.Boolean") ||
267                     typeName.equals("int") ||
268                     typeName.equals("java.lang.Integer") ||
269                     typeName.equals("float") ||
270                     typeName.equals("java.lang.Float") ||
271                     typeName.equals("double") ||
272                     typeName.equals("java.lang.Double") ||
273                     typeName.equals("long") ||
274                     typeName.equals("java.lang.Long")) {
275                 try {
276                     sb.append("\""+name+"\":");
277                     sb.append(field.get(t));
278                     sb.append(",");
279                 } catch (Exception e) {
280                     if(DEBUG)
281                         e.printStackTrace();
282                 }
283             } else if(typeName.equals("java.util.List") ||
284                     typeName.equals("java.util.ArrayList")){
285                 try {
286                     List<?> objList = (List<?>) field.get(t);
287                     if(null != objList && objList.size() > 0) {
288                         sb.append("\""+name+"\":");
289                         sb.append("[");
290                         String toJson = listToJson((List<?>) field.get(t));
291                         sb.append(toJson);
292                         sb.setCharAt(sb.length()-1, ']');
293                         sb.append(",");
294                     }
295                 } catch (Exception e) {
296                     if(DEBUG)
297                         e.printStackTrace();
298                 }
299             } else {
300                 try {
301                     sb.append("\""+name+"\":");
302                     sb.append("{");
303                     sb.append(objectToJson(field.get(t)));
304                     sb.setCharAt(sb.length()-1, '}');
305                     sb.append(",");
306                 } catch (Exception e) {
307                     if(DEBUG)
308                         e.printStackTrace();
309                 }
310             }
311 
312         }
313         if(sb.length() == 1) {
314             sb.append("}");
315         }
316         sb.setCharAt(sb.length()-1, '}');
317         return sb.toString();
318     }
319 
320     /**
321      * 将 List 对象编码为 JSON格式
322      *
323      * @param objList 待封装的对象集合
324      * @return String:封装后JSONArray String格式
325      * @version 1.0
326      * @date 2015-10-11
327      */
328     private static<T> String listToJson(List<T> objList) {
329         final StringBuilder sb = new StringBuilder();
330         for (T t : objList) {
331             if(t instanceof String) {
332                 sb.append(stringToJson((String) t));
333                 sb.append(",");
334             } else if(t instanceof Boolean ||
335                     t instanceof Integer ||
336                     t instanceof Float ||
337                     t instanceof Double) {
338                 sb.append(t);
339                 sb.append(",");
340             } else {
341                 sb.append(objectToJson(t));
342                 sb.append(",");
343             }
344         }
345         return sb.toString();
346     }
347 
348     /**
349      * 将 String 对象编码为 JSON格式,只需处理好特殊字符
350      *
351      * @param str String 对象
352      * @return String:JSON格式
353      * @version 1.0
354      * @date 2015-10-11
355      */
356     private static String stringToJson(final String str) {
357         if(str == null || str.length() == 0) {
358             return "\"\"";
359         }
360         final StringBuilder sb = new StringBuilder(str.length() + 2 << 4);
361         sb.append('\"');
362         for (int i = 0; i < str.length(); i++) {
363             final char c = str.charAt(i);
364 
365             sb.append(c == '\"' ? "\\\"" : c == '\\' ? "\\\\"
366                     : c == '/' ? "\\/" : c == '\b' ? "\\b" : c == '\f' ? "\\f"
367                     : c == '\n' ? "\\n" : c == '\r' ? "\\r"
368                     : c == '\t' ? "\\t" : c);
369         }
370         sb.append('\"');
371         return sb.toString();
372     }
373 
374     /**
375      * 由JSONObject生成Bean对象
376      *
377      * @param job
378      * @param className 待生成Bean对象的名称
379      * @param outCount 外部类的个数
380      * @return LinkedList<String>: 生成的Bean对象
381      * @version 1.0
382      * @date 2015-10-16
383      */
384     private static String createObject(JSONObject job, String className, int outCount) {
385         final StringBuilder sb = new StringBuilder();
386         String separator = System.getProperty("line.separator");
387 
388         // 生成的Bean类前部的缩进空间
389         String classFrontSpace = "";
390         // 生成的Bean类字段前部的缩进空间
391         String fieldFrontSpace = "    ";
392         for (int i = 0; i < outCount; i++) {
393             classFrontSpace += "    ";
394             fieldFrontSpace += "    ";
395         }
396 
397         sb.append(classFrontSpace + "public class " + className + " {");
398 
399         Iterator<?> it = job.keys();
400         while (it.hasNext()) {
401             String key = (String) it.next();
402             try {
403                 Object obj = job.get(key);
404                 if(obj instanceof JSONArray) {
405                     // 判断类是否为基本数据类型,如果为自定义类则字段类型取将key的首字母大写作为内部类名称
406                     String fieldType = ((JSONArray)obj).get(0) instanceof JSONObject ?
407                             "" : ((JSONArray)obj).get(0).getClass().getSimpleName();
408                     if(fieldType == "") {
409                         fieldType = String.valueOf(Character.isUpperCase(key.charAt(0)) ?
410                                 key.charAt(0) : Character.toUpperCase(key.charAt(0))) + key.substring(1);
411                     }
412                     sb.append(separator);
413                     sb.append(fieldFrontSpace + "public List<" + fieldType + "> " + key + ";");
414 
415                     // 如果字段类型为自定义类类型,则取JSONArray中第一个JSONObject生成Bean
416                     if(((JSONArray)obj).get(0) instanceof JSONObject) {
417                         sb.append(separator);
418                         sb.append(separator);
419                         sb.append(fieldFrontSpace + "/** "+ fieldType +" is the inner class of "+ className +" */");
420                         sb.append(separator);
421                         sb.append(createObject((JSONObject)((JSONArray)obj).get(0), fieldType, outCount+1));
422                     }
423                 } else if(obj instanceof JSONObject) {
424                     String fieldType = String.valueOf(Character.isUpperCase(key.charAt(0)) ?
425                             key.charAt(0) : Character.toUpperCase(key.charAt(0))) + key.substring(1);
426                     sb.append(separator);
427                     sb.append(fieldFrontSpace + "public List<" + fieldType + "> " + key + ";");
428                     sb.append(separator);
429                     sb.append(separator);
430                     sb.append(fieldFrontSpace + "/** "+ fieldType +" is the inner class of "+ className +" */");
431                     sb.append(separator);
432                     sb.append(createObject((JSONObject)obj, fieldType, outCount+1));
433                 } else {
434                     String type = obj.getClass().getSimpleName();
435                     sb.append(separator);
436                     sb.append(fieldFrontSpace + "public " + type + " " + key + ";");
437                 }
438             } catch (JSONException e) {
439                 e.printStackTrace();
440             }
441         }
442 
443         sb.append(separator);
444         sb.append(classFrontSpace + "}");
445         sb.append(separator);
446 
447         return sb.toString();
448     }
449 
450 }

 

 String json = LocalFileUtils.getStringFormAsset(this, "testbean1.json");
 String createBean = JsonTool.createBean(json, "TestBean1");
 System.out.println(createBean);

 

posted on 2016-03-11 13:20  大米稀饭  阅读(307)  评论(0编辑  收藏  举报