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 *
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 *
031 * 该工具类使用的 {@code JSON} 转换引擎是
032 * {@code Google Gson}。 下面是工具类的使用案例:
033 *
034 *
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 userList = new LinkedList();
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(){}.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 *
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} 数据 - "{}"。 */
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} 的 @Since 注解常用的版本号常量 - {@code 1.0}。 */
087 public static final double SINCE_VERSION_10 = 1.0d;
088
089 /** {@code Google Gson} 的 @Since 注解常用的版本号常量 - {@code 1.1}。 */
090 public static final double SINCE_VERSION_11 = 1.1d;
091
092 /** {@code Google Gson} 的 @Since 注解常用的版本号常量 - {@code 1.2}。 */
093 public static final double SINCE_VERSION_12 = 1.2d;
094
095 /** {@code Google Gson} 的 @Until 注解常用的版本号常量 - {@code 1.0}。 */
096 public static final double UNTIL_VERSION_10 = SINCE_VERSION_10;
097
098 /** {@code Google Gson} 的 @Until 注解常用的版本号常量 - {@code 1.1}。 */
099 public static final double UNTIL_VERSION_11 = SINCE_VERSION_11;
100
101 /** {@code Google Gson} 的 @Until 注解常用的版本号常量 - {@code 1.2}。 */
102 public static final double UNTIL_VERSION_12 = SINCE_VERSION_12;
103
104 /**
105 *
106
* JSONUtils instances should NOT be constructed in standard programming. Instead,
107
* the class should be used as JSONUtils.fromJson("foo");.
108
*
109 *
110
* This constructor is public to permit tools that require a JavaBean instance to operate.
111
*
112 */
113 public JSONUtils() {
114 super();
115 }
116
117 /**
118 * 将给定的目标对象根据指定的条件参数转换成 {@code JSON} 格式的字符串。
119 *
120 * 该方法转换发生错误时,不会抛出任何异常。若发生错误时,曾通对象返回 "{}"; 集合或数组对象返回 "[]"
121 *
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 == null) return 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} 格式的字符串。此方法只用来转换普通的 {@code JavaBean} 对象。
146 *
147 *
148 *
149 *
150 *
151 *
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, null, false, null, null, true);
159 }
160
161 /**
162 * 将给定的目标对象转换成 {@code JSON} 格式的字符串。此方法只用来转换普通的 {@code JavaBean} 对象。
163 *
164 *
165 *
166 *
167 *
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, null, false, null, datePattern, true);
176 }
177
178 /**
179 * 将给定的目标对象转换成 {@code JSON} 格式的字符串。此方法只用来转换普通的 {@code JavaBean} 对象。
180 *
181 *
182 *
183 *
184 *
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, null, false, version, null, true);
193 }
194
195 /**
196 * 将给定的目标对象转换成 {@code JSON} 格式的字符串。此方法只用来转换普通的 {@code JavaBean} 对象。
197 *
198 *
199 *
200 *
201 *
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, null, false, null, null, excludesFieldsWithoutExpose);
210 }
211
212 /**
213 * 将给定的目标对象转换成 {@code JSON} 格式的字符串。此方法只用来转换普通的 {@code JavaBean} 对象。
214 *
215 *
216 *
217 *
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, boolean excludesFieldsWithoutExpose) {
226 return toJson(target, null, false, version, null, excludesFieldsWithoutExpose);
227 }
228
229 /**
230 * 将给定的目标对象转换成 {@code JSON} 格式的字符串。此方法通常用来转换使用泛型的对象。
231 *
232 *
233 *
234 *
235 *
236 *
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, false, null, null, true);
245 }
246
247 /**
248 * 将给定的目标对象转换成 {@code JSON} 格式的字符串。此方法通常用来转换使用泛型的对象。
249 *
250 *
251 *
252 *
253 *
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, null, true);
263 }
264
265 /**
266 * 将给定的目标对象转换成 {@code JSON} 格式的字符串。此方法通常用来转换使用泛型的对象。
267 *
268 *
269 *
270 *
271 *
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, boolean excludesFieldsWithoutExpose) {
280 return toJson(target, targetType, false, null, null, excludesFieldsWithoutExpose);
281 }
282
283 /**
284 * 将给定的目标对象转换成 {@code JSON} 格式的字符串。此方法通常用来转换使用泛型的对象。
285 *
286 *
287 *
288 *
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, boolean excludesFieldsWithoutExpose) {
298 return toJson(target, targetType, false, version, null, excludesFieldsWithoutExpose);
299 }
300
301 /**
302 * 将给定的 {@code JSON} 字符串转换成指定的类型对象。
303 *
304 * @param 要转换的目标类型。
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 fromJson(String json, TypeToken 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 要转换的目标类型。
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 fromJson(String json, TypeToken token) {
338 return fromJson(json, token, null);
339 }
340
341 /**
342 * 将给定的 {@code JSON} 字符串转换成指定的类型对象。此方法通常用来转换普通的 {@code JavaBean} 对象。
343 *
344 * @param 要转换的目标类型。
345 * @param json 给定的 {@code JSON} 字符串。
346 * @param clazz 要转换的目标类。
347 * @param datePattern 日期格式模式。
348 * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
349 * @since 1.0
350 */
351 public static T fromJson(String json, Class 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} 字符串转换成指定的类型对象。此方法通常用来转换普通的 {@code JavaBean} 对象。
370 *
371 * @param 要转换的目标类型。
372 * @param json 给定的 {@code JSON} 字符串。
373 * @param clazz 要转换的目标类。
374 * @return 给定的 {@code JSON} 字符串表示的指定的类型对象。
375 * @since 1.0
376 */
377 public static T fromJson(String json, Class clazz) {
378 return fromJson(json, clazz, null);
379 }
380
381 /**
382 * 将给定的目标对象根据{@code GsonBuilder} 所指定的条件参数转换成 {@code JSON} 格式的字符串。
383 *
384 * 该方法转换发生错误时,不会抛出任何异常。若发生错误时,{@code JavaBean} 对象返回 "{}"; 集合或数组对象返回
385 * "[]"。 其本基本类型,返回相应的基本值。
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 == null) return 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 }