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" : c == 'f' ? "\f"
367 : c == '
' ? "\n" : c == '
' ? "\r"
368 : c == ' ' ? "\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);