Java操作JSON的便捷工具类(Gson)

001 /**
002  * Copyright 2010 Fuchun.
003  *
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  *     http://www.apache.org/licenses/LICENSE-2.0
008  *
009  * Unless required by applicable law or agreed to in writing, software
010  * distributed under the License is distributed on an "AS IS" BASIS,
011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012  * See the License for the specific language governing permissions and
013  * limitations under the License.
014  */
015  
016 package my.tools;
017 import java.lang.reflect.Type;
018 import java.util.Collection;
019 import java.util.Enumeration;
020 import java.util.Iterator;
021 import org.slf4j.Logger;
022 import org.slf4j.LoggerFactory;
023 import com.google.gson.Gson;
024 import com.google.gson.GsonBuilder;
025 import com.google.gson.reflect.TypeToken;
026 import org.apache.commons.lang.StringUtils;
027  
028 /**
029  * 包含操作 {@code JSON} 数据的常用方法的工具类。
030  * <p />
031  * 该工具类使用的 {@code JSON} 转换引擎是 <a href="http://code.google.com/p/google-gson/" mce_href="http://code.google.com/p/google-gson/" target="_blank">
032  * {@code Google Gson}</a>。 下面是工具类的使用案例:
033  *
034  * <pre>
035  * public class User {
036  *     @SerializedName("pwd")
037  *     private String password;
038  *     @Expose
039  *     @SerializedName("uname")
040  *     private String username;
041  *     @Expose
042  *     @Since(1.1)
043  *     private String gender;
044  *     @Expose
045  *     @Since(1.0)
046  *     private String sex;
047  *     
048  *     public User() {}
049  *     public User(String username, String password, String gender) {
050  *         // user constructor code... ... ...
051  *     }
052  *     
053  *     public String getUsername()
054  *     ... ... ...
055  * }
056  * List<User> userList = new LinkedList<User>();
057  * User jack = new User("Jack", "123456", "Male");
058  * User marry = new User("Marry", "888888", "Female");
059  * userList.add(jack);
060  * userList.add(marry);
061  * Type targetType = new TypeToken<List<User>>(){}.getType();
062  * String sUserList1 = JSONUtils.toJson(userList, targetType);
063  * sUserList1 ----> [{"uname":"jack","gender":"Male","sex":"Male"},{"uname":"marry","gender":"Female","sex":"Female"}]
064  * String sUserList2 = JSONUtils.toJson(userList, targetType, false);
065  * sUserList2 ----> [{"uname":"jack","pwd":"123456","gender":"Male","sex":"Male"},{"uname":"marry","pwd":"888888","gender":"Female","sex":"Female"}]
066  * String sUserList3 = JSONUtils.toJson(userList, targetType, 1.0d, true);
067  * sUserList3 ----> [{"uname":"jack","sex":"Male"},{"uname":"marry","sex":"Female"}]
068  * </pre>
069  *
070  * @author Fuchun
071  * @since ay-commons-lang 1.0
072  * @version 1.1.0
073  */
074 public class JSONUtils {
075     private static final Logger LOGGER = LoggerFactory.getLogger(JSONUtils.class);
076  
077     /** 空的 {@code JSON} 数据 - <code>"{}"</code>。 */
078     public static final String EMPTY_JSON = "{}";
079  
080     /** 空的 {@code JSON} 数组(集合)数据 - {@code "[]"}。 */
081     public static final String EMPTY_JSON_ARRAY = "[]";
082  
083     /** 默认的 {@code JSON} 日期/时间字段的格式化模式。 */
084     public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss SSS";
085  
086     /** {@code Google Gson} 的 <code>@Since</code> 注解常用的版本号常量 - {@code 1.0}。 */
087     public static final double SINCE_VERSION_10 = 1.0d;
088  
089     /** {@code Google Gson} 的 <code>@Since</code> 注解常用的版本号常量 - {@code 1.1}。 */
090     public static final double SINCE_VERSION_11 = 1.1d;
091  
092     /** {@code Google Gson} 的 <code>@Since</code> 注解常用的版本号常量 - {@code 1.2}。 */
093     public static final double SINCE_VERSION_12 = 1.2d;
094  
095     /** {@code Google Gson} 的 <code>@Until</code> 注解常用的版本号常量 - {@code 1.0}。 */
096     public static final double UNTIL_VERSION_10 = SINCE_VERSION_10;
097  
098     /** {@code Google Gson} 的 <code>@Until</code> 注解常用的版本号常量 - {@code 1.1}。 */
099     public static final double UNTIL_VERSION_11 = SINCE_VERSION_11;
100  
101     /** {@code Google Gson} 的 <code>@Until</code> 注解常用的版本号常量 - {@code 1.2}。 */
102     public static final double UNTIL_VERSION_12 = SINCE_VERSION_12;
103  
104     /**
105      * <p>
106      * <code>JSONUtils</code> instances should NOT be constructed in standard programming. Instead,
107      * the class should be used as <code>JSONUtils.fromJson("foo");</code>.
108      * </p>
109      * <p>
110      * This constructor is public to permit tools that require a JavaBean instance to operate.
111      * </p>
112      */
113     public JSONUtils() {
114         super();
115     }
116  
117     /**
118      * 将给定的目标对象根据指定的条件参数转换成 {@code JSON} 格式的字符串。
119      * <p />
120      * <strong>该方法转换发生错误时,不会抛出任何异常。若发生错误时,曾通对象返回 <code>"{}"</code>; 集合或数组对象返回 <code>"[]"</code>
121      * </strong>
122      *
123      * @param target 目标对象。
124      * @param targetType 目标对象的类型。
125      * @param isSerializeNulls 是否序列化 {@code null} 值字段。
126      * @param version 字段的版本号注解。
127      * @param datePattern 日期字段的格式化模式。
128      * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
129      * @return 目标对象的 {@code JSON} 格式的字符串。
130      * @since 1.0
131      */
132     public static String toJson(Object target, Type targetType, boolean isSerializeNulls, Double version,
133             String datePattern, boolean excludesFieldsWithoutExpose) {
134         if (target == nullreturn EMPTY_JSON;
135         GsonBuilder builder = new GsonBuilder();
136         if (isSerializeNulls) builder.serializeNulls();
137         if (version != null) builder.setVersion(version.doubleValue());
138         if (StringUtils.isBlank(datePattern)) datePattern = DEFAULT_DATE_PATTERN;
139         builder.setDateFormat(datePattern);
140         if (excludesFieldsWithoutExpose) builder.excludeFieldsWithoutExposeAnnotation();
141         return toJson(target, targetType, builder);
142     }
143  
144     /**
145      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
146      * <ul>
147      * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
148      * <li>该方法不会转换 {@code null} 值字段;</li>
149      * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
150      * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
151      * </ul>
152      *
153      * @param target 要转换成 {@code JSON} 的目标对象。
154      * @return 目标对象的 {@code JSON} 格式的字符串。
155      * @since 1.0
156      */
157     public static String toJson(Object target) {
158         return toJson(target, nullfalsenullnulltrue);
159     }
160  
161     /**
162      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
163      * <ul>
164      * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
165      * <li>该方法不会转换 {@code null} 值字段;</li>
166      * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
167      * </ul>
168      *
169      * @param target 要转换成 {@code JSON} 的目标对象。
170      * @param datePattern 日期字段的格式化模式。
171      * @return 目标对象的 {@code JSON} 格式的字符串。
172      * @since 1.0
173      */
174     public static String toJson(Object target, String datePattern) {
175         return toJson(target, nullfalsenull, datePattern, true);
176     }
177  
178     /**
179      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
180      * <ul>
181      * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
182      * <li>该方法不会转换 {@code null} 值字段;</li>
183      * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
184      * </ul>
185      *
186      * @param target 要转换成 {@code JSON} 的目标对象。
187      * @param version 字段的版本号注解({@literal @Since})。
188      * @return 目标对象的 {@code JSON} 格式的字符串。
189      * @since 1.0
190      */
191     public static String toJson(Object target, Double version) {
192         return toJson(target, nullfalse, version, nulltrue);
193     }
194  
195     /**
196      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
197      * <ul>
198      * <li>该方法不会转换 {@code null} 值字段;</li>
199      * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
200      * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
201      * </ul>
202      *
203      * @param target 要转换成 {@code JSON} 的目标对象。
204      * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
205      * @return 目标对象的 {@code JSON} 格式的字符串。
206      * @since 1.0
207      */
208     public static String toJson(Object target, boolean excludesFieldsWithoutExpose) {
209         return toJson(target, nullfalsenullnull, excludesFieldsWithoutExpose);
210     }
211  
212     /**
213      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法只用来转换普通的 {@code JavaBean} 对象。</strong>
214      * <ul>
215      * <li>该方法不会转换 {@code null} 值字段;</li>
216      * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
217      * </ul>
218      *
219      * @param target 要转换成 {@code JSON} 的目标对象。
220      * @param version 字段的版本号注解({@literal @Since})。
221      * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
222      * @return 目标对象的 {@code JSON} 格式的字符串。
223      * @since 1.0
224      */
225     public static String toJson(Object target, Double version, booleanexcludesFieldsWithoutExpose) {
226         return toJson(target, nullfalse, version, null, excludesFieldsWithoutExpose);
227     }
228  
229     /**
230      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法通常用来转换使用泛型的对象。</strong>
231      * <ul>
232      * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
233      * <li>该方法不会转换 {@code null} 值字段;</li>
234      * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
235      * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSSS};</li>
236      * </ul>
237      *
238      * @param target 要转换成 {@code JSON} 的目标对象。
239      * @param targetType 目标对象的类型。
240      * @return 目标对象的 {@code JSON} 格式的字符串。
241      * @since 1.0
242      */
243     public static String toJson(Object target, Type targetType) {
244         return toJson(target, targetType, falsenullnulltrue);
245     }
246  
247     /**
248      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法通常用来转换使用泛型的对象。</strong>
249      * <ul>
250      * <li>该方法只会转换标有 {@literal @Expose} 注解的字段;</li>
251      * <li>该方法不会转换 {@code null} 值字段;</li>
252      * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSSS};</li>
253      * </ul>
254      *
255      * @param target 要转换成 {@code JSON} 的目标对象。
256      * @param targetType 目标对象的类型。
257      * @param version 字段的版本号注解({@literal @Since})。
258      * @return 目标对象的 {@code JSON} 格式的字符串。
259      * @since 1.0
260      */
261     public static String toJson(Object target, Type targetType, Double version) {
262         return toJson(target, targetType, false, version, nulltrue);
263     }
264  
265     /**
266      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法通常用来转换使用泛型的对象。</strong>
267      * <ul>
268      * <li>该方法不会转换 {@code null} 值字段;</li>
269      * <li>该方法会转换所有未标注或已标注 {@literal @Since} 的字段;</li>
270      * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
271      * </ul>
272      *
273      * @param target 要转换成 {@code JSON} 的目标对象。
274      * @param targetType 目标对象的类型。
275      * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
276      * @return 目标对象的 {@code JSON} 格式的字符串。
277      * @since 1.0
278      */
279     public static String toJson(Object target, Type targetType, booleanexcludesFieldsWithoutExpose) {
280         return toJson(target, targetType, falsenullnull, excludesFieldsWithoutExpose);
281     }
282  
283     /**
284      * 将给定的目标对象转换成 {@code JSON} 格式的字符串。<strong>此方法通常用来转换使用泛型的对象。</strong>
285      * <ul>
286      * <li>该方法不会转换 {@code null} 值字段;</li>
287      * <li>该方法转换时使用默认的 日期/时间 格式化模式 - {@code yyyy-MM-dd HH:mm:ss SSS};</li>
288      * </ul>
289      *
290      * @param target 要转换成 {@code JSON} 的目标对象。
291      * @param targetType 目标对象的类型。
292      * @param version 字段的版本号注解({@literal @Since})。
293      * @param excludesFieldsWithoutExpose 是否排除未标注 {@literal @Expose} 注解的字段。
294      * @return 目标对象的 {@code JSON} 格式的字符串。
295      * @since 1.0
296      */
297     public static String toJson(Object target, Type targetType, Double version, booleanexcludesFieldsWithoutExpose) {
298         return toJson(target, targetType, false, version, null, excludesFieldsWithoutExpose);
299     }
300  
301     /**
302      * 将给定的 {@code JSON} 字符串转换成指定的类型对象。
303      *
304      * @param <T> 要转换的目标类型。
305      * @param json 给定的 {@code JSON} 字符串。
306      * @param token {@code com.google.gson.reflect.TypeToken} 的类型指示类对象。
307      * @param datePattern 日期格式模式。
308      * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
309      * @since 1.0
310      */
311     public static <T> T fromJson(String json, TypeToken<T> token, String datePattern) {
312         if (StringUtils.isBlank(json)) {
313             return null;
314         }
315         GsonBuilder builder = new GsonBuilder();
316         if (StringUtils.isBlank(datePattern)) {
317             datePattern = DEFAULT_DATE_PATTERN;
318         }
319         Gson gson = builder.create();
320         try {
321             return gson.fromJson(json, token.getType());
322         catch (Exception ex) {
323             LOGGER.error(json + " 无法转换为 " + token.getRawType().getName() + " 对象!", ex);
324             return null;
325         }
326     }
327  
328     /**
329      * 将给定的 {@code JSON} 字符串转换成指定的类型对象。
330      *
331      * @param <T> 要转换的目标类型。
332      * @param json 给定的 {@code JSON} 字符串。
333      * @param token {@code com.google.gson.reflect.TypeToken} 的类型指示类对象。
334      * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
335      * @since 1.0
336      */
337     public static <T> T fromJson(String json, TypeToken<T> token) {
338         return fromJson(json, token, null);
339     }
340  
341     /**
342      * 将给定的 {@code JSON} 字符串转换成指定的类型对象。<strong>此方法通常用来转换普通的 {@code JavaBean} 对象。</strong>
343      *
344      * @param <T> 要转换的目标类型。
345      * @param json 给定的 {@code JSON} 字符串。
346      * @param clazz 要转换的目标类。
347      * @param datePattern 日期格式模式。
348      * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
349      * @since 1.0
350      */
351     public static <T> T fromJson(String json, Class<T> clazz, String datePattern) {
352         if (StringUtils.isBlank(json)) {
353             return null;
354         }
355         GsonBuilder builder = new GsonBuilder();
356         if (StringUtils.isBlank(datePattern)) {
357             datePattern = DEFAULT_DATE_PATTERN;
358         }
359         Gson gson = builder.create();
360         try {
361             return gson.fromJson(json, clazz);
362         catch (Exception ex) {
363             LOGGER.error(json + " 无法转换为 " + clazz.getName() + " 对象!", ex);
364             return null;
365         }
366     }
367  
368     /**
369      * 将给定的 {@code JSON} 字符串转换成指定的类型对象。<strong>此方法通常用来转换普通的 {@code JavaBean} 对象。</strong>
370      *
371      * @param <T> 要转换的目标类型。
372      * @param json 给定的 {@code JSON} 字符串。
373      * @param clazz 要转换的目标类。
374      * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
375      * @since 1.0
376      */
377     public static <T> T fromJson(String json, Class<T> clazz) {
378         return fromJson(json, clazz, null);
379     }
380  
381     /**
382      * 将给定的目标对象根据{@code GsonBuilder} 所指定的条件参数转换成 {@code JSON} 格式的字符串。
383      * <p />
384      * 该方法转换发生错误时,不会抛出任何异常。若发生错误时,{@code JavaBean} 对象返回 <code>"{}"</code>; 集合或数组对象返回
385      * <code>"[]"</code>。 其本基本类型,返回相应的基本值。
386      *
387      * @param target 目标对象。
388      * @param targetType 目标对象的类型。
389      * @param builder 可定制的{@code Gson} 构建器。
390      * @return 目标对象的 {@code JSON} 格式的字符串。
391      * @since 1.1
392      */
393     public static String toJson(Object target, Type targetType, GsonBuilder builder) {
394         if (target == nullreturn EMPTY_JSON;
395         Gson gson = null;
396         if (builder == null) {
397             gson = new Gson();
398         else {
399             gson = builder.create();
400         }
401         String result = EMPTY_JSON;
402         try {
403             if (targetType == null) {
404                 result = gson.toJson(target);
405             else {
406                 result = gson.toJson(target, targetType);
407             }
408         catch (Exception ex) {
409             LOGGER.warn("目标对象 " + target.getClass().getName() + " 转换 JSON 字符串时,发生异常!", ex);
410             if (target instanceof Collection<?> || target instanceof Iterator<?> || target instanceof Enumeration<?>
411                     || target.getClass().isArray()) {
412                 result = EMPTY_JSON_ARRAY;
413             }
414         }
415         return result;
416     }
417 }
原文地址:https://www.cnblogs.com/top5/p/2336493.html