Java实现操作JSON的便捷工具类完整实例【重写Google的Gson】

时间:2022-02-17 18:54:33

本文实例讲述了Java实现操作JSON的便捷工具类。分享给大家供大家参考,具体如下:

对于JSON数据格式的处理,自开发Java以来,已用过多种JSON的开源工具,用得最好,也用得最High的恐怕要属GoogleGson了。

特别为它写了一个工具类,放入常备工具中,方便使用。下面是为GSON 1.5版本重写的工具类。

依赖包:

slf4j-api-1.6.0.jar
slf4j-log4j12-1.6.0.jar
log4j-1.2.15.jar
gson-1.5.jar

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
/**
 * Copyright 2010 Fuchun.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package my.tools;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang.StringUtils;
/**
 * 包含操作 {@code JSON} 数据的常用方法的工具类。
 * <p />
 * 该工具类使用的 {@code JSON} 转换引擎是 <a href="http://code.google.com/p/google-gson/" rel="external nofollow" rel="external nofollow" mce_href="http://code.google.com/p/google-gson/" rel="external nofollow" rel="external nofollow" target="_blank">
 * {@code Google Gson}</a>。 下面是工具类的使用案例:
 *
 * <pre>
 * public class User {
 *   @SerializedName("pwd")
 *   private String password;
 *   @Expose
 *   @SerializedName("uname")
 *   private String username;
 *   @Expose
 *   @Since(1.1)
 *   private String gender;
 *   @Expose
 *   @Since(1.0)
 *   private String sex;
 *
 *   public User() {}
 *   public User(String username, String password, String gender) {
 *     // user constructor code... ... ...
 *   }
 *
 *   public String getUsername()
 *   ... ... ...
 * }
 * List<User> userList = new LinkedList<User>();
 * User jack = new User("Jack", "123456", "Male");
 * User marry = new User("Marry", "888888", "Female");
 * userList.add(jack);
 * userList.add(marry);
 * Type targetType = new TypeToken<List<User>>(){}.getType();
 * String sUserList1 = JSONUtils.toJson(userList, targetType);
 * sUserList1 ----> [{"uname":"jack","gender":"Male","sex":"Male"},{"uname":"marry","gender":"Female","sex":"Female"}]
 * String sUserList2 = JSONUtils.toJson(userList, targetType, false);
 * sUserList2 ----> [{"uname":"jack","pwd":"123456","gender":"Male","sex":"Male"},{"uname":"marry","pwd":"888888","gender":"Female","sex":"Female"}]
 * String sUserList3 = JSONUtils.toJson(userList, targetType, 1.0d, true);
 * sUserList3 ----> [{"uname":"jack","sex":"Male"},{"uname":"marry","sex":"Female"}]
 * </pre>
 *
 * @author Fuchun
 * @since ay-commons-lang 1.0
 * @version 1.1.0
 */
public class JSONUtils {
  private static final Logger LOGGER = LoggerFactory.getLogger(JSONUtils.class);
  /** 空的 {@code JSON} 数据 - <code>"{}"</code>。 */
  public static final String EMPTY_JSON = "{}";
  /** 空的 {@code JSON} 数组(集合)数据 - {@code "[]"}。 */
  public static final String EMPTY_JSON_ARRAY = "[]";
  /** 默认的 {@code JSON} 日期/时间字段的格式化模式。 */
  public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss SSS";
  /** {@code Google Gson} 的 <code>@Since</code> 注解常用的版本号常量 - {@code 1.0}。 */
  public static final double SINCE_VERSION_10 = 1.0d;
  /** {@code Google Gson} 的 <code>@Since</code> 注解常用的版本号常量 - {@code 1.1}。 */
  public static final double SINCE_VERSION_11 = 1.1d;
  /** {@code Google Gson} 的 <code>@Since</code> 注解常用的版本号常量 - {@code 1.2}。 */
  public static final double SINCE_VERSION_12 = 1.2d;
  /** {@code Google Gson} 的 <code>@Until</code> 注解常用的版本号常量 - {@code 1.0}。 */
  public static final double UNTIL_VERSION_10 = SINCE_VERSION_10;
  /** {@code Google Gson} 的 <code>@Until</code> 注解常用的版本号常量 - {@code 1.1}。 */
  public static final double UNTIL_VERSION_11 = SINCE_VERSION_11;
  /** {@code Google Gson} 的 <code>@Until</code> 注解常用的版本号常量 - {@code 1.2}。 */
  public static final double UNTIL_VERSION_12 = SINCE_VERSION_12;
  /**
   * <p>
   * <code>JSONUtils</code> instances should NOT be constructed in standard programming. Instead,
   * the class should be used as <code>JSONUtils.fromJson("foo");</code>.
   * </p>
   * <p>
   * This constructor is public to permit tools that require a JavaBean instance to operate.
   * </p>
   */
  public JSONUtils() {
    super();
  }
  /**
   * 将给定的目标对象根据指定的条件参数转换成 {@code JSON} 格式的字符串。
   * <p />
   * <strong>该方法转换发生错误时,不会抛出任何异常。若发生错误时,曾通对象返回 <code>"{}"</code>; 集合或数组对象返回 <code>"[]"</code>
   * </strong>
   *
   * @param target 目标对象。
   * @param targetType 目标对象的类型。
   * @param isSerializeNulls 是否序列化 {@code null} 值字段。
   * @param version 字段的版本号注解。
   * @param datePattern 日期字段的格式化模式。
   * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, Type targetType, boolean isSerializeNulls, Double version,
      String datePattern, boolean excludesFieldsWithoutExpose) {
    if (target == null) return EMPTY_JSON;
    GsonBuilder builder = new GsonBuilder();
    if (isSerializeNulls) builder.serializeNulls();
    if (version != null) builder.setVersion(version.doubleValue());
    if (StringUtils.isBlank(datePattern)) datePattern = DEFAULT_DATE_PATTERN;
    builder.setDateFormat(datePattern);
    if (excludesFieldsWithoutExpose) builder.excludeFieldsWithoutExposeAnnotation();
    return toJson(target, targetType, builder);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
   * <ul>
   * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
   * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target) {
    return toJson(target, null, false, null, null, true);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
   * <ul>
   * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @param datePattern 日期字段的格式化模式。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, String datePattern) {
    return toJson(target, null, false, null, datePattern, true);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
   * <ul>
   * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @param version 字段的版本号注解({@literal @Since})。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, Double version) {
    return toJson(target, null, false, version, null, true);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
   * <ul>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
   * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, boolean excludesFieldsWithoutExpose) {
    return toJson(target, null, false, null, null, excludesFieldsWithoutExpose);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
   * <ul>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @param version 字段的版本号注解({@literal @Since})。
   * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, Double version, boolean excludesFieldsWithoutExpose) {
    return toJson(target, null, false, version, null, excludesFieldsWithoutExpose);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法通常用来转换使用泛型的对象。</strong>
   * <ul>
   * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
   * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSSS};</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @param targetType 目标对象的类型。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, Type targetType) {
    return toJson(target, targetType, false, null, null, true);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法通常用来转换使用泛型的对象。</strong>
   * <ul>
   * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSSS};</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @param targetType 目标对象的类型。
   * @param version 字段的版本号注解({@literal @Since})。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, Type targetType, Double version) {
    return toJson(target, targetType, false, version, null, true);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法通常用来转换使用泛型的对象。</strong>
   * <ul>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
   * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @param targetType 目标对象的类型。
   * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, Type targetType, boolean excludesFieldsWithoutExpose) {
    return toJson(target, targetType, false, null, null, excludesFieldsWithoutExpose);
  }
  /**
   * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法通常用来转换使用泛型的对象。</strong>
   * <ul>
   * <li>该方法不会转换 {@code null} 值字段;</li>
   * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
   * </ul>
   *
   * @param target 要转换成 {@code JSON} 的目标对象。
   * @param targetType 目标对象的类型。
   * @param version 字段的版本号注解({@literal @Since})。
   * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.0
   */
  public static String toJson(Object target, Type targetType, Double version, boolean excludesFieldsWithoutExpose) {
    return toJson(target, targetType, false, version, null, excludesFieldsWithoutExpose);
  }
  /**
   * 将给定的 {@code JSON} 字符串转换成指定的类型对象。
   *
   * @param <T> 要转换的目标类型。
   * @param json 给定的 {@code JSON} 字符串。
   * @param token {@code com.google.gson.reflect.TypeToken} 的类型指示类对象。
   * @param datePattern 日期格式模式。
   * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
   * @since 1.0
   */
  public static <T> T fromJson(String json, TypeToken<T> token, String datePattern) {
    if (StringUtils.isBlank(json)) {
      return null;
    }
    GsonBuilder builder = new GsonBuilder();
    if (StringUtils.isBlank(datePattern)) {
      datePattern = DEFAULT_DATE_PATTERN;
    }
    Gson gson = builder.create();
    try {
      return gson.fromJson(json, token.getType());
    } catch (Exception ex) {
      LOGGER.error(json + " 无法转换为 " + token.getRawType().getName() + " 对象!", ex);
      return null;
    }
  }
  /**
   * 将给定的 {@code JSON} 字符串转换成指定的类型对象。
   *
   * @param <T> 要转换的目标类型。
   * @param json 给定的 {@code JSON} 字符串。
   * @param token {@code com.google.gson.reflect.TypeToken} 的类型指示类对象。
   * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
   * @since 1.0
   */
  public static <T> T fromJson(String json, TypeToken<T> token) {
    return fromJson(json, token, null);
  }
  /**
   * 将给定的 {@code JSON} 字符串转换成指定的类型对象。<strong>此方法通常用来转换普通的 {@code JavaBean} 对象。</strong>
   *
   * @param <T> 要转换的目标类型。
   * @param json 给定的 {@code JSON} 字符串。
   * @param clazz 要转换的目标类。
   * @param datePattern 日期格式模式。
   * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
   * @since 1.0
   */
  public static <T> T fromJson(String json, Class<T> clazz, String datePattern) {
    if (StringUtils.isBlank(json)) {
      return null;
    }
    GsonBuilder builder = new GsonBuilder();
    if (StringUtils.isBlank(datePattern)) {
      datePattern = DEFAULT_DATE_PATTERN;
    }
    Gson gson = builder.create();
    try {
      return gson.fromJson(json, clazz);
    } catch (Exception ex) {
      LOGGER.error(json + " 无法转换为 " + clazz.getName() + " 对象!", ex);
      return null;
    }
  }
  /**
   * 将给定的 {@code JSON} 字符串转换成指定的类型对象。<strong>此方法通常用来转换普通的 {@code JavaBean} 对象。</strong>
   *
   * @param <T> 要转换的目标类型。
   * @param json 给定的 {@code JSON} 字符串。
   * @param clazz 要转换的目标类。
   * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
   * @since 1.0
   */
  public static <T> T fromJson(String json, Class<T> clazz) {
    return fromJson(json, clazz, null);
  }
  /**
   * 将给定的目标对象根据{@code GsonBuilder} 所指定的条件参数转换成 {@code JSON} 格式的字符串。
   * <p />
   * 该方法转换发生错误时,不会抛出任何异常。若发生错误时,{@code JavaBean} 对象返回 <code>"{}"</code>; 集合或数组对象返回
   * <code>"[]"</code>。 其本基本类型,返回相应的基本值。
   *
   * @param target 目标对象。
   * @param targetType 目标对象的类型。
   * @param builder 可定制的{@code Gson} 构建器。
   * @return 目标对象的 {@code JSON} 格式的字符串。
   * @since 1.1
   */
  public static String toJson(Object target, Type targetType, GsonBuilder builder) {
    if (target == null) return EMPTY_JSON;
    Gson gson = null;
    if (builder == null) {
      gson = new Gson();
    } else {
      gson = builder.create();
    }
    String result = EMPTY_JSON;
    try {
      if (targetType == null) {
        result = gson.toJson(target);
      } else {
        result = gson.toJson(target, targetType);
      }
    } catch (Exception ex) {
      LOGGER.warn("目标对象 " + target.getClass().getName() + " 转换 JSON 字符串时,发生异常!", ex);
      if (target instanceof Collection<?> || target instanceof Iterator<?> || target instanceof Enumeration<?>
          || target.getClass().isArray()) {
        result = EMPTY_JSON_ARRAY;
      }
    }
    return result;
  }
}

希望本文所述对大家java程序设计有所帮助。

原文链接:http://blog.csdn.net/xusongsong520/article/details/7941847