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