1 /* 2 * Copyright (C) 2008 Google Inc. 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 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.gson; 18 19 import com.google.gson.internal.ConstructorConstructor; 20 import com.google.gson.internal.Excluder; 21 import com.google.gson.internal.GsonBuildConfig; 22 import com.google.gson.internal.LazilyParsedNumber; 23 import com.google.gson.internal.Primitives; 24 import com.google.gson.internal.Streams; 25 import com.google.gson.internal.bind.ArrayTypeAdapter; 26 import com.google.gson.internal.bind.CollectionTypeAdapterFactory; 27 import com.google.gson.internal.bind.DateTypeAdapter; 28 import com.google.gson.internal.bind.JsonAdapterAnnotationTypeAdapterFactory; 29 import com.google.gson.internal.bind.JsonTreeReader; 30 import com.google.gson.internal.bind.JsonTreeWriter; 31 import com.google.gson.internal.bind.MapTypeAdapterFactory; 32 import com.google.gson.internal.bind.NumberTypeAdapter; 33 import com.google.gson.internal.bind.ObjectTypeAdapter; 34 import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory; 35 import com.google.gson.internal.bind.SerializationDelegatingTypeAdapter; 36 import com.google.gson.internal.bind.TypeAdapters; 37 import com.google.gson.internal.sql.SqlTypesSupport; 38 import com.google.gson.reflect.TypeToken; 39 import com.google.gson.stream.JsonReader; 40 import com.google.gson.stream.JsonToken; 41 import com.google.gson.stream.JsonWriter; 42 import com.google.gson.stream.MalformedJsonException; 43 import java.io.EOFException; 44 import java.io.IOException; 45 import java.io.Reader; 46 import java.io.StringReader; 47 import java.io.StringWriter; 48 import java.io.Writer; 49 import java.lang.reflect.Type; 50 import java.math.BigDecimal; 51 import java.math.BigInteger; 52 import java.text.DateFormat; 53 import java.util.ArrayList; 54 import java.util.Collections; 55 import java.util.HashMap; 56 import java.util.List; 57 import java.util.Map; 58 import java.util.Objects; 59 import java.util.concurrent.ConcurrentHashMap; 60 import java.util.concurrent.ConcurrentMap; 61 import java.util.concurrent.atomic.AtomicLong; 62 import java.util.concurrent.atomic.AtomicLongArray; 63 64 /** 65 * This is the main class for using Gson. Gson is typically used by first constructing a 66 * Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)} 67 * methods on it. Gson instances are Thread-safe so you can reuse them freely across multiple 68 * threads. 69 * 70 * <p>You can create a Gson instance by invoking {@code new Gson()} if the default configuration 71 * is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various 72 * configuration options such as versioning support, pretty printing, custom 73 * {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.</p> 74 * 75 * <p>Here is an example of how Gson is used for a simple Class: 76 * 77 * <pre> 78 * Gson gson = new Gson(); // Or use new GsonBuilder().create(); 79 * MyType target = new MyType(); 80 * String json = gson.toJson(target); // serializes target to JSON 81 * MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2 82 * </pre> 83 * 84 * <p>If the type of the object that you are converting is a {@code ParameterizedType} 85 * (i.e. has at least one type argument, for example {@code List<MyType>}) then for 86 * deserialization you must use a {@code fromJson} method with {@link Type} or {@link TypeToken} 87 * parameter to specify the parameterized type. For serialization specifying a {@code Type} 88 * or {@code TypeToken} is optional, otherwise Gson will use the runtime type of the object. 89 * {@link TypeToken} is a class provided by Gson which helps creating parameterized types. 90 * Here is an example showing how this can be done: 91 * <pre> 92 * TypeToken<List<MyType>> listType = new TypeToken<List<MyType>>() {}; 93 * List<MyType> target = new LinkedList<MyType>(); 94 * target.add(new MyType(1, "abc")); 95 * 96 * Gson gson = new Gson(); 97 * // For serialization you normally do not have to specify the type, Gson will use 98 * // the runtime type of the objects, however you can also specify it explicitly 99 * String json = gson.toJson(target, listType.getType()); 100 * 101 * // But for deserialization you have to specify the type 102 * List<MyType> target2 = gson.fromJson(json, listType); 103 * </pre> 104 * 105 * <p>See the <a href="https://github.com/google/gson/blob/master/UserGuide.md">Gson User Guide</a> 106 * for a more complete set of examples.</p> 107 * 108 * <h2>Lenient JSON handling</h2> 109 * For legacy reasons most of the {@code Gson} methods allow JSON data which does not 110 * comply with the JSON specification, regardless of whether {@link GsonBuilder#setLenient()} 111 * is used or not. If this behavior is not desired, the following workarounds can be used: 112 * 113 * <h3>Serialization</h3> 114 * <ol> 115 * <li>Use {@link #getAdapter(Class)} to obtain the adapter for the type to be serialized 116 * <li>When using an existing {@code JsonWriter}, manually apply the writer settings of this 117 * {@code Gson} instance listed by {@link #newJsonWriter(Writer)}.<br> 118 * Otherwise, when not using an existing {@code JsonWriter}, use {@link #newJsonWriter(Writer)} 119 * to construct one. 120 * <li>Call {@link TypeAdapter#write(JsonWriter, Object)} 121 * </ol> 122 * 123 * <h3>Deserialization</h3> 124 * <ol> 125 * <li>Use {@link #getAdapter(Class)} to obtain the adapter for the type to be deserialized 126 * <li>When using an existing {@code JsonReader}, manually apply the reader settings of this 127 * {@code Gson} instance listed by {@link #newJsonReader(Reader)}.<br> 128 * Otherwise, when not using an existing {@code JsonReader}, use {@link #newJsonReader(Reader)} 129 * to construct one. 130 * <li>Call {@link TypeAdapter#read(JsonReader)} 131 * <li>Call {@link JsonReader#peek()} and verify that the result is {@link JsonToken#END_DOCUMENT} 132 * to make sure there is no trailing data 133 * </ol> 134 * 135 * @see TypeToken 136 * 137 * @author Inderjeet Singh 138 * @author Joel Leitch 139 * @author Jesse Wilson 140 */ 141 public final class Gson { 142 static final boolean DEFAULT_JSON_NON_EXECUTABLE = false; 143 static final boolean DEFAULT_LENIENT = false; 144 static final boolean DEFAULT_PRETTY_PRINT = false; 145 static final boolean DEFAULT_ESCAPE_HTML = true; 146 static final boolean DEFAULT_SERIALIZE_NULLS = false; 147 static final boolean DEFAULT_COMPLEX_MAP_KEYS = false; 148 static final boolean DEFAULT_SPECIALIZE_FLOAT_VALUES = false; 149 static final boolean DEFAULT_USE_JDK_UNSAFE = true; 150 static final String DEFAULT_DATE_PATTERN = null; 151 static final FieldNamingStrategy DEFAULT_FIELD_NAMING_STRATEGY = FieldNamingPolicy.IDENTITY; 152 static final ToNumberStrategy DEFAULT_OBJECT_TO_NUMBER_STRATEGY = ToNumberPolicy.DOUBLE; 153 static final ToNumberStrategy DEFAULT_NUMBER_TO_NUMBER_STRATEGY = ToNumberPolicy.LAZILY_PARSED_NUMBER; 154 155 private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n"; 156 157 /** 158 * This thread local guards against reentrant calls to getAdapter(). In 159 * certain object graphs, creating an adapter for a type may recursively 160 * require an adapter for the same type! Without intervention, the recursive 161 * lookup would stack overflow. We cheat by returning a proxy type adapter. 162 * The proxy is wired up once the initial adapter has been created. 163 */ 164 private final ThreadLocal<Map<TypeToken<?>, FutureTypeAdapter<?>>> calls 165 = new ThreadLocal<>(); 166 167 private final ConcurrentMap<TypeToken<?>, TypeAdapter<?>> typeTokenCache = new ConcurrentHashMap<>(); 168 169 private final ConstructorConstructor constructorConstructor; 170 private final JsonAdapterAnnotationTypeAdapterFactory jsonAdapterFactory; 171 172 final List<TypeAdapterFactory> factories; 173 174 final Excluder excluder; 175 final FieldNamingStrategy fieldNamingStrategy; 176 final Map<Type, InstanceCreator<?>> instanceCreators; 177 final boolean serializeNulls; 178 final boolean complexMapKeySerialization; 179 final boolean generateNonExecutableJson; 180 final boolean htmlSafe; 181 final boolean prettyPrinting; 182 final boolean lenient; 183 final boolean serializeSpecialFloatingPointValues; 184 final boolean useJdkUnsafe; 185 final String datePattern; 186 final int dateStyle; 187 final int timeStyle; 188 final LongSerializationPolicy longSerializationPolicy; 189 final List<TypeAdapterFactory> builderFactories; 190 final List<TypeAdapterFactory> builderHierarchyFactories; 191 final ToNumberStrategy objectToNumberStrategy; 192 final ToNumberStrategy numberToNumberStrategy; 193 final List<ReflectionAccessFilter> reflectionFilters; 194 195 /** 196 * Constructs a Gson object with default configuration. The default configuration has the 197 * following settings: 198 * <ul> 199 * <li>The JSON generated by <code>toJson</code> methods is in compact representation. This 200 * means that all the unneeded white-space is removed. You can change this behavior with 201 * {@link GsonBuilder#setPrettyPrinting()}. </li> 202 * <li>The generated JSON omits all the fields that are null. Note that nulls in arrays are 203 * kept as is since an array is an ordered list. Moreover, if a field is not null, but its 204 * generated JSON is empty, the field is kept. You can configure Gson to serialize null values 205 * by setting {@link GsonBuilder#serializeNulls()}.</li> 206 * <li>Gson provides default serialization and deserialization for Enums, {@link Map}, 207 * {@link java.net.URL}, {@link java.net.URI}, {@link java.util.Locale}, {@link java.util.Date}, 208 * {@link java.math.BigDecimal}, and {@link java.math.BigInteger} classes. If you would prefer 209 * to change the default representation, you can do so by registering a type adapter through 210 * {@link GsonBuilder#registerTypeAdapter(Type, Object)}. </li> 211 * <li>The default Date format is same as {@link java.text.DateFormat#DEFAULT}. This format 212 * ignores the millisecond portion of the date during serialization. You can change 213 * this by invoking {@link GsonBuilder#setDateFormat(int)} or 214 * {@link GsonBuilder#setDateFormat(String)}. </li> 215 * <li>By default, Gson ignores the {@link com.google.gson.annotations.Expose} annotation. 216 * You can enable Gson to serialize/deserialize only those fields marked with this annotation 217 * through {@link GsonBuilder#excludeFieldsWithoutExposeAnnotation()}. </li> 218 * <li>By default, Gson ignores the {@link com.google.gson.annotations.Since} annotation. You 219 * can enable Gson to use this annotation through {@link GsonBuilder#setVersion(double)}.</li> 220 * <li>The default field naming policy for the output JSON is same as in Java. So, a Java class 221 * field <code>versionNumber</code> will be output as <code>"versionNumber"</code> in 222 * JSON. The same rules are applied for mapping incoming JSON to the Java classes. You can 223 * change this policy through {@link GsonBuilder#setFieldNamingPolicy(FieldNamingPolicy)}.</li> 224 * <li>By default, Gson excludes <code>transient</code> or <code>static</code> fields from 225 * consideration for serialization and deserialization. You can change this behavior through 226 * {@link GsonBuilder#excludeFieldsWithModifiers(int...)}.</li> 227 * </ul> 228 */ Gson()229 public Gson() { 230 this(Excluder.DEFAULT, DEFAULT_FIELD_NAMING_STRATEGY, 231 Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS, 232 DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML, 233 DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES, 234 DEFAULT_USE_JDK_UNSAFE, 235 LongSerializationPolicy.DEFAULT, DEFAULT_DATE_PATTERN, DateFormat.DEFAULT, DateFormat.DEFAULT, 236 Collections.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(), 237 Collections.<TypeAdapterFactory>emptyList(), DEFAULT_OBJECT_TO_NUMBER_STRATEGY, DEFAULT_NUMBER_TO_NUMBER_STRATEGY, 238 Collections.<ReflectionAccessFilter>emptyList()); 239 } 240 Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy, Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues, boolean useJdkUnsafe, LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle, int timeStyle, List<TypeAdapterFactory> builderFactories, List<TypeAdapterFactory> builderHierarchyFactories, List<TypeAdapterFactory> factoriesToBeAdded, ToNumberStrategy objectToNumberStrategy, ToNumberStrategy numberToNumberStrategy, List<ReflectionAccessFilter> reflectionFilters)241 Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy, 242 Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, 243 boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, 244 boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues, 245 boolean useJdkUnsafe, 246 LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle, 247 int timeStyle, List<TypeAdapterFactory> builderFactories, 248 List<TypeAdapterFactory> builderHierarchyFactories, 249 List<TypeAdapterFactory> factoriesToBeAdded, 250 ToNumberStrategy objectToNumberStrategy, ToNumberStrategy numberToNumberStrategy, 251 List<ReflectionAccessFilter> reflectionFilters) { 252 this.excluder = excluder; 253 this.fieldNamingStrategy = fieldNamingStrategy; 254 this.instanceCreators = instanceCreators; 255 this.constructorConstructor = new ConstructorConstructor(instanceCreators, useJdkUnsafe, reflectionFilters); 256 this.serializeNulls = serializeNulls; 257 this.complexMapKeySerialization = complexMapKeySerialization; 258 this.generateNonExecutableJson = generateNonExecutableGson; 259 this.htmlSafe = htmlSafe; 260 this.prettyPrinting = prettyPrinting; 261 this.lenient = lenient; 262 this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues; 263 this.useJdkUnsafe = useJdkUnsafe; 264 this.longSerializationPolicy = longSerializationPolicy; 265 this.datePattern = datePattern; 266 this.dateStyle = dateStyle; 267 this.timeStyle = timeStyle; 268 this.builderFactories = builderFactories; 269 this.builderHierarchyFactories = builderHierarchyFactories; 270 this.objectToNumberStrategy = objectToNumberStrategy; 271 this.numberToNumberStrategy = numberToNumberStrategy; 272 this.reflectionFilters = reflectionFilters; 273 274 List<TypeAdapterFactory> factories = new ArrayList<>(); 275 276 // built-in type adapters that cannot be overridden 277 factories.add(TypeAdapters.JSON_ELEMENT_FACTORY); 278 factories.add(ObjectTypeAdapter.getFactory(objectToNumberStrategy)); 279 280 // the excluder must precede all adapters that handle user-defined types 281 factories.add(excluder); 282 283 // users' type adapters 284 factories.addAll(factoriesToBeAdded); 285 286 // type adapters for basic platform types 287 factories.add(TypeAdapters.STRING_FACTORY); 288 factories.add(TypeAdapters.INTEGER_FACTORY); 289 factories.add(TypeAdapters.BOOLEAN_FACTORY); 290 factories.add(TypeAdapters.BYTE_FACTORY); 291 factories.add(TypeAdapters.SHORT_FACTORY); 292 TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy); 293 factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter)); 294 factories.add(TypeAdapters.newFactory(double.class, Double.class, 295 doubleAdapter(serializeSpecialFloatingPointValues))); 296 factories.add(TypeAdapters.newFactory(float.class, Float.class, 297 floatAdapter(serializeSpecialFloatingPointValues))); 298 factories.add(NumberTypeAdapter.getFactory(numberToNumberStrategy)); 299 factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY); 300 factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY); 301 factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter))); 302 factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter))); 303 factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY); 304 factories.add(TypeAdapters.CHARACTER_FACTORY); 305 factories.add(TypeAdapters.STRING_BUILDER_FACTORY); 306 factories.add(TypeAdapters.STRING_BUFFER_FACTORY); 307 factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL)); 308 factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER)); 309 // Add adapter for LazilyParsedNumber because user can obtain it from Gson and then try to serialize it again 310 factories.add(TypeAdapters.newFactory(LazilyParsedNumber.class, TypeAdapters.LAZILY_PARSED_NUMBER)); 311 factories.add(TypeAdapters.URL_FACTORY); 312 factories.add(TypeAdapters.URI_FACTORY); 313 factories.add(TypeAdapters.UUID_FACTORY); 314 factories.add(TypeAdapters.CURRENCY_FACTORY); 315 factories.add(TypeAdapters.LOCALE_FACTORY); 316 factories.add(TypeAdapters.INET_ADDRESS_FACTORY); 317 factories.add(TypeAdapters.BIT_SET_FACTORY); 318 factories.add(DateTypeAdapter.FACTORY); 319 factories.add(TypeAdapters.CALENDAR_FACTORY); 320 321 if (SqlTypesSupport.SUPPORTS_SQL_TYPES) { 322 factories.add(SqlTypesSupport.TIME_FACTORY); 323 factories.add(SqlTypesSupport.DATE_FACTORY); 324 factories.add(SqlTypesSupport.TIMESTAMP_FACTORY); 325 } 326 327 factories.add(ArrayTypeAdapter.FACTORY); 328 factories.add(TypeAdapters.CLASS_FACTORY); 329 330 // type adapters for composite and user-defined types 331 factories.add(new CollectionTypeAdapterFactory(constructorConstructor)); 332 factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization)); 333 this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor); 334 factories.add(jsonAdapterFactory); 335 factories.add(TypeAdapters.ENUM_FACTORY); 336 factories.add(new ReflectiveTypeAdapterFactory( 337 constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory, reflectionFilters)); 338 339 this.factories = Collections.unmodifiableList(factories); 340 } 341 342 /** 343 * Returns a new GsonBuilder containing all custom factories and configuration used by the current 344 * instance. 345 * 346 * @return a GsonBuilder instance. 347 * @since 2.8.3 348 */ newBuilder()349 public GsonBuilder newBuilder() { 350 return new GsonBuilder(this); 351 } 352 353 /** 354 * @deprecated This method by accident exposes an internal Gson class; it might be removed in a 355 * future version. 356 */ 357 @Deprecated excluder()358 public Excluder excluder() { 359 return excluder; 360 } 361 362 /** 363 * Returns the field naming strategy used by this Gson instance. 364 * 365 * @see GsonBuilder#setFieldNamingStrategy(FieldNamingStrategy) 366 */ fieldNamingStrategy()367 public FieldNamingStrategy fieldNamingStrategy() { 368 return fieldNamingStrategy; 369 } 370 371 /** 372 * Returns whether this Gson instance is serializing JSON object properties with 373 * {@code null} values, or just omits them. 374 * 375 * @see GsonBuilder#serializeNulls() 376 */ serializeNulls()377 public boolean serializeNulls() { 378 return serializeNulls; 379 } 380 381 /** 382 * Returns whether this Gson instance produces JSON output which is 383 * HTML-safe, that means all HTML characters are escaped. 384 * 385 * @see GsonBuilder#disableHtmlEscaping() 386 */ htmlSafe()387 public boolean htmlSafe() { 388 return htmlSafe; 389 } 390 doubleAdapter(boolean serializeSpecialFloatingPointValues)391 private TypeAdapter<Number> doubleAdapter(boolean serializeSpecialFloatingPointValues) { 392 if (serializeSpecialFloatingPointValues) { 393 return TypeAdapters.DOUBLE; 394 } 395 return new TypeAdapter<Number>() { 396 @Override public Double read(JsonReader in) throws IOException { 397 if (in.peek() == JsonToken.NULL) { 398 in.nextNull(); 399 return null; 400 } 401 return in.nextDouble(); 402 } 403 @Override public void write(JsonWriter out, Number value) throws IOException { 404 if (value == null) { 405 out.nullValue(); 406 return; 407 } 408 double doubleValue = value.doubleValue(); 409 checkValidFloatingPoint(doubleValue); 410 out.value(doubleValue); 411 } 412 }; 413 } 414 415 private TypeAdapter<Number> floatAdapter(boolean serializeSpecialFloatingPointValues) { 416 if (serializeSpecialFloatingPointValues) { 417 return TypeAdapters.FLOAT; 418 } 419 return new TypeAdapter<Number>() { 420 @Override public Float read(JsonReader in) throws IOException { 421 if (in.peek() == JsonToken.NULL) { 422 in.nextNull(); 423 return null; 424 } 425 return (float) in.nextDouble(); 426 } 427 @Override public void write(JsonWriter out, Number value) throws IOException { 428 if (value == null) { 429 out.nullValue(); 430 return; 431 } 432 float floatValue = value.floatValue(); 433 checkValidFloatingPoint(floatValue); 434 // For backward compatibility don't call `JsonWriter.value(float)` because that method has 435 // been newly added and not all custom JsonWriter implementations might override it yet 436 Number floatNumber = value instanceof Float ? value : floatValue; 437 out.value(floatNumber); 438 } 439 }; 440 } 441 442 static void checkValidFloatingPoint(double value) { 443 if (Double.isNaN(value) || Double.isInfinite(value)) { 444 throw new IllegalArgumentException(value 445 + " is not a valid double value as per JSON specification. To override this" 446 + " behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method."); 447 } 448 } 449 450 private static TypeAdapter<Number> longAdapter(LongSerializationPolicy longSerializationPolicy) { 451 if (longSerializationPolicy == LongSerializationPolicy.DEFAULT) { 452 return TypeAdapters.LONG; 453 } 454 return new TypeAdapter<Number>() { 455 @Override public Number read(JsonReader in) throws IOException { 456 if (in.peek() == JsonToken.NULL) { 457 in.nextNull(); 458 return null; 459 } 460 return in.nextLong(); 461 } 462 @Override public void write(JsonWriter out, Number value) throws IOException { 463 if (value == null) { 464 out.nullValue(); 465 return; 466 } 467 out.value(value.toString()); 468 } 469 }; 470 } 471 472 private static TypeAdapter<AtomicLong> atomicLongAdapter(final TypeAdapter<Number> longAdapter) { 473 return new TypeAdapter<AtomicLong>() { 474 @Override public void write(JsonWriter out, AtomicLong value) throws IOException { 475 longAdapter.write(out, value.get()); 476 } 477 @Override public AtomicLong read(JsonReader in) throws IOException { 478 Number value = longAdapter.read(in); 479 return new AtomicLong(value.longValue()); 480 } 481 }.nullSafe(); 482 } 483 484 private static TypeAdapter<AtomicLongArray> atomicLongArrayAdapter(final TypeAdapter<Number> longAdapter) { 485 return new TypeAdapter<AtomicLongArray>() { 486 @Override public void write(JsonWriter out, AtomicLongArray value) throws IOException { 487 out.beginArray(); 488 for (int i = 0, length = value.length(); i < length; i++) { 489 longAdapter.write(out, value.get(i)); 490 } 491 out.endArray(); 492 } 493 @Override public AtomicLongArray read(JsonReader in) throws IOException { 494 List<Long> list = new ArrayList<>(); 495 in.beginArray(); 496 while (in.hasNext()) { 497 long value = longAdapter.read(in).longValue(); 498 list.add(value); 499 } 500 in.endArray(); 501 int length = list.size(); 502 AtomicLongArray array = new AtomicLongArray(length); 503 for (int i = 0; i < length; ++i) { 504 array.set(i, list.get(i)); 505 } 506 return array; 507 } 508 }.nullSafe(); 509 } 510 511 /** 512 * Returns the type adapter for {@code} type. 513 * 514 * @throws IllegalArgumentException if this GSON cannot serialize and 515 * deserialize {@code type}. 516 */ 517 public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) { 518 Objects.requireNonNull(type, "type must not be null"); 519 TypeAdapter<?> cached = typeTokenCache.get(type); 520 if (cached != null) { 521 @SuppressWarnings("unchecked") 522 TypeAdapter<T> adapter = (TypeAdapter<T>) cached; 523 return adapter; 524 } 525 526 Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get(); 527 boolean requiresThreadLocalCleanup = false; 528 if (threadCalls == null) { 529 threadCalls = new HashMap<>(); 530 calls.set(threadCalls); 531 requiresThreadLocalCleanup = true; 532 } 533 534 // the key and value type parameters always agree 535 @SuppressWarnings("unchecked") 536 FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type); 537 if (ongoingCall != null) { 538 return ongoingCall; 539 } 540 541 try { 542 FutureTypeAdapter<T> call = new FutureTypeAdapter<>(); 543 threadCalls.put(type, call); 544 545 for (TypeAdapterFactory factory : factories) { 546 TypeAdapter<T> candidate = factory.create(this, type); 547 if (candidate != null) { 548 @SuppressWarnings("unchecked") 549 TypeAdapter<T> existingAdapter = (TypeAdapter<T>) typeTokenCache.putIfAbsent(type, candidate); 550 // If other thread concurrently added adapter prefer that one instead 551 if (existingAdapter != null) { 552 candidate = existingAdapter; 553 } 554 555 call.setDelegate(candidate); 556 return candidate; 557 } 558 } 559 throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type); 560 } finally { 561 threadCalls.remove(type); 562 563 if (requiresThreadLocalCleanup) { 564 calls.remove(); 565 } 566 } 567 } 568 569 /** 570 * This method is used to get an alternate type adapter for the specified type. This is used 571 * to access a type adapter that is overridden by a {@link TypeAdapterFactory} that you 572 * may have registered. This features is typically used when you want to register a type 573 * adapter that does a little bit of work but then delegates further processing to the Gson 574 * default type adapter. Here is an example: 575 * <p>Let's say we want to write a type adapter that counts the number of objects being read 576 * from or written to JSON. We can achieve this by writing a type adapter factory that uses 577 * the <code>getDelegateAdapter</code> method: 578 * <pre> {@code 579 * class StatsTypeAdapterFactory implements TypeAdapterFactory { 580 * public int numReads = 0; 581 * public int numWrites = 0; 582 * public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { 583 * final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); 584 * return new TypeAdapter<T>() { 585 * public void write(JsonWriter out, T value) throws IOException { 586 * ++numWrites; 587 * delegate.write(out, value); 588 * } 589 * public T read(JsonReader in) throws IOException { 590 * ++numReads; 591 * return delegate.read(in); 592 * } 593 * }; 594 * } 595 * } 596 * } </pre> 597 * This factory can now be used like this: 598 * <pre> {@code 599 * StatsTypeAdapterFactory stats = new StatsTypeAdapterFactory(); 600 * Gson gson = new GsonBuilder().registerTypeAdapterFactory(stats).create(); 601 * // Call gson.toJson() and fromJson methods on objects 602 * System.out.println("Num JSON reads" + stats.numReads); 603 * System.out.println("Num JSON writes" + stats.numWrites); 604 * }</pre> 605 * Note that this call will skip all factories registered before {@code skipPast}. In case of 606 * multiple TypeAdapterFactories registered it is up to the caller of this function to insure 607 * that the order of registration does not prevent this method from reaching a factory they 608 * would expect to reply from this call. 609 * Note that since you can not override type adapter factories for String and Java primitive 610 * types, our stats factory will not count the number of String or primitives that will be 611 * read or written. 612 * @param skipPast The type adapter factory that needs to be skipped while searching for 613 * a matching type adapter. In most cases, you should just pass <i>this</i> (the type adapter 614 * factory from where {@code getDelegateAdapter} method is being invoked). 615 * @param type Type for which the delegate adapter is being searched for. 616 * 617 * @since 2.2 618 */ 619 public <T> TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken<T> type) { 620 // Hack. If the skipPast factory isn't registered, assume the factory is being requested via 621 // our @JsonAdapter annotation. 622 if (!factories.contains(skipPast)) { 623 skipPast = jsonAdapterFactory; 624 } 625 626 boolean skipPastFound = false; 627 for (TypeAdapterFactory factory : factories) { 628 if (!skipPastFound) { 629 if (factory == skipPast) { 630 skipPastFound = true; 631 } 632 continue; 633 } 634 635 TypeAdapter<T> candidate = factory.create(this, type); 636 if (candidate != null) { 637 return candidate; 638 } 639 } 640 throw new IllegalArgumentException("GSON cannot serialize " + type); 641 } 642 643 /** 644 * Returns the type adapter for {@code} type. 645 * 646 * @throws IllegalArgumentException if this GSON cannot serialize and 647 * deserialize {@code type}. 648 */ 649 public <T> TypeAdapter<T> getAdapter(Class<T> type) { 650 return getAdapter(TypeToken.get(type)); 651 } 652 653 /** 654 * This method serializes the specified object into its equivalent representation as a tree of 655 * {@link JsonElement}s. This method should be used when the specified object is not a generic 656 * type. This method uses {@link Class#getClass()} to get the type for the specified object, but 657 * the {@code getClass()} loses the generic type information because of the Type Erasure feature 658 * of Java. Note that this method works fine if any of the object fields are of generic type, 659 * just the object itself should not be of a generic type. If the object is of generic type, use 660 * {@link #toJsonTree(Object, Type)} instead. 661 * 662 * @param src the object for which JSON representation is to be created 663 * @return JSON representation of {@code src}. 664 * @since 1.4 665 * 666 * @see #toJsonTree(Object, Type) 667 */ 668 public JsonElement toJsonTree(Object src) { 669 if (src == null) { 670 return JsonNull.INSTANCE; 671 } 672 return toJsonTree(src, src.getClass()); 673 } 674 675 /** 676 * This method serializes the specified object, including those of generic types, into its 677 * equivalent representation as a tree of {@link JsonElement}s. This method must be used if the 678 * specified object is a generic type. For non-generic objects, use {@link #toJsonTree(Object)} 679 * instead. 680 * 681 * @param src the object for which JSON representation is to be created 682 * @param typeOfSrc The specific genericized type of src. You can obtain 683 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example, 684 * to get the type for {@code Collection<Foo>}, you should use: 685 * <pre> 686 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType(); 687 * </pre> 688 * @return Json representation of {@code src} 689 * @since 1.4 690 * 691 * @see #toJsonTree(Object) 692 */ 693 public JsonElement toJsonTree(Object src, Type typeOfSrc) { 694 JsonTreeWriter writer = new JsonTreeWriter(); 695 toJson(src, typeOfSrc, writer); 696 return writer.get(); 697 } 698 699 /** 700 * This method serializes the specified object into its equivalent JSON representation. 701 * This method should be used when the specified object is not a generic type. This method uses 702 * {@link Class#getClass()} to get the type for the specified object, but the 703 * {@code getClass()} loses the generic type information because of the Type Erasure feature 704 * of Java. Note that this method works fine if any of the object fields are of generic type, 705 * just the object itself should not be of a generic type. If the object is of generic type, use 706 * {@link #toJson(Object, Type)} instead. If you want to write out the object to a 707 * {@link Writer}, use {@link #toJson(Object, Appendable)} instead. 708 * 709 * @param src the object for which JSON representation is to be created 710 * @return Json representation of {@code src}. 711 * 712 * @see #toJson(Object, Appendable) 713 * @see #toJson(Object, Type) 714 */ 715 public String toJson(Object src) { 716 if (src == null) { 717 return toJson(JsonNull.INSTANCE); 718 } 719 return toJson(src, src.getClass()); 720 } 721 722 /** 723 * This method serializes the specified object, including those of generic types, into its 724 * equivalent JSON representation. This method must be used if the specified object is a generic 725 * type. For non-generic objects, use {@link #toJson(Object)} instead. If you want to write out 726 * the object to a {@link Appendable}, use {@link #toJson(Object, Type, Appendable)} instead. 727 * 728 * @param src the object for which JSON representation is to be created 729 * @param typeOfSrc The specific genericized type of src. You can obtain 730 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example, 731 * to get the type for {@code Collection<Foo>}, you should use: 732 * <pre> 733 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType(); 734 * </pre> 735 * @return JSON representation of {@code src} 736 * 737 * @see #toJson(Object, Type, Appendable) 738 * @see #toJson(Object) 739 */ 740 public String toJson(Object src, Type typeOfSrc) { 741 StringWriter writer = new StringWriter(); 742 toJson(src, typeOfSrc, writer); 743 return writer.toString(); 744 } 745 746 /** 747 * This method serializes the specified object into its equivalent JSON representation and 748 * writes it to the writer. 749 * This method should be used when the specified object is not a generic type. This method uses 750 * {@link Class#getClass()} to get the type for the specified object, but the 751 * {@code getClass()} loses the generic type information because of the Type Erasure feature 752 * of Java. Note that this method works fine if any of the object fields are of generic type, 753 * just the object itself should not be of a generic type. If the object is of generic type, use 754 * {@link #toJson(Object, Type, Appendable)} instead. 755 * 756 * @param src the object for which JSON representation is to be created 757 * @param writer Writer to which the JSON representation needs to be written 758 * @throws JsonIOException if there was a problem writing to the writer 759 * @since 1.2 760 * 761 * @see #toJson(Object) 762 * @see #toJson(Object, Type, Appendable) 763 */ 764 public void toJson(Object src, Appendable writer) throws JsonIOException { 765 if (src != null) { 766 toJson(src, src.getClass(), writer); 767 } else { 768 toJson(JsonNull.INSTANCE, writer); 769 } 770 } 771 772 /** 773 * This method serializes the specified object, including those of generic types, into its 774 * equivalent JSON representation and writes it to the writer. 775 * This method must be used if the specified object is a generic type. For non-generic objects, 776 * use {@link #toJson(Object, Appendable)} instead. 777 * 778 * @param src the object for which JSON representation is to be created 779 * @param typeOfSrc The specific genericized type of src. You can obtain 780 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example, 781 * to get the type for {@code Collection<Foo>}, you should use: 782 * <pre> 783 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType(); 784 * </pre> 785 * @param writer Writer to which the JSON representation of src needs to be written. 786 * @throws JsonIOException if there was a problem writing to the writer 787 * @since 1.2 788 * 789 * @see #toJson(Object, Type) 790 * @see #toJson(Object, Appendable) 791 */ 792 public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException { 793 try { 794 JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer)); 795 toJson(src, typeOfSrc, jsonWriter); 796 } catch (IOException e) { 797 throw new JsonIOException(e); 798 } 799 } 800 801 /** 802 * Writes the JSON representation of {@code src} of type {@code typeOfSrc} to 803 * {@code writer}. 804 * 805 * <p>The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode}, 806 * regardless of the lenient mode setting of the provided writer. The lenient mode setting 807 * of the writer is restored once this method returns. 808 * 809 * <p>The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance 810 * (configured by the {@link GsonBuilder}) are applied, and the original settings of the 811 * writer are restored once this method returns. 812 * 813 * @throws JsonIOException if there was a problem writing to the writer 814 */ 815 public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException { 816 @SuppressWarnings("unchecked") 817 TypeAdapter<Object> adapter = (TypeAdapter<Object>) getAdapter(TypeToken.get(typeOfSrc)); 818 boolean oldLenient = writer.isLenient(); 819 writer.setLenient(true); 820 boolean oldHtmlSafe = writer.isHtmlSafe(); 821 writer.setHtmlSafe(htmlSafe); 822 boolean oldSerializeNulls = writer.getSerializeNulls(); 823 writer.setSerializeNulls(serializeNulls); 824 try { 825 adapter.write(writer, src); 826 } catch (IOException e) { 827 throw new JsonIOException(e); 828 } catch (AssertionError e) { 829 AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage()); 830 error.initCause(e); 831 throw error; 832 } finally { 833 writer.setLenient(oldLenient); 834 writer.setHtmlSafe(oldHtmlSafe); 835 writer.setSerializeNulls(oldSerializeNulls); 836 } 837 } 838 839 /** 840 * Converts a tree of {@link JsonElement}s into its equivalent JSON representation. 841 * 842 * @param jsonElement root of a tree of {@link JsonElement}s 843 * @return JSON String representation of the tree 844 * @since 1.4 845 */ 846 public String toJson(JsonElement jsonElement) { 847 StringWriter writer = new StringWriter(); 848 toJson(jsonElement, writer); 849 return writer.toString(); 850 } 851 852 /** 853 * Writes out the equivalent JSON for a tree of {@link JsonElement}s. 854 * 855 * @param jsonElement root of a tree of {@link JsonElement}s 856 * @param writer Writer to which the JSON representation needs to be written 857 * @throws JsonIOException if there was a problem writing to the writer 858 * @since 1.4 859 */ 860 public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOException { 861 try { 862 JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer)); 863 toJson(jsonElement, jsonWriter); 864 } catch (IOException e) { 865 throw new JsonIOException(e); 866 } 867 } 868 869 /** 870 * Returns a new JSON writer configured for the settings on this Gson instance. 871 * 872 * <p>The following settings are considered: 873 * <ul> 874 * <li>{@link GsonBuilder#disableHtmlEscaping()}</li> 875 * <li>{@link GsonBuilder#generateNonExecutableJson()}</li> 876 * <li>{@link GsonBuilder#serializeNulls()}</li> 877 * <li>{@link GsonBuilder#setLenient()}</li> 878 * <li>{@link GsonBuilder#setPrettyPrinting()}</li> 879 * </ul> 880 */ 881 public JsonWriter newJsonWriter(Writer writer) throws IOException { 882 if (generateNonExecutableJson) { 883 writer.write(JSON_NON_EXECUTABLE_PREFIX); 884 } 885 JsonWriter jsonWriter = new JsonWriter(writer); 886 if (prettyPrinting) { 887 jsonWriter.setIndent(" "); 888 } 889 jsonWriter.setHtmlSafe(htmlSafe); 890 jsonWriter.setLenient(lenient); 891 jsonWriter.setSerializeNulls(serializeNulls); 892 return jsonWriter; 893 } 894 895 /** 896 * Returns a new JSON reader configured for the settings on this Gson instance. 897 * 898 * <p>The following settings are considered: 899 * <ul> 900 * <li>{@link GsonBuilder#setLenient()}</li> 901 * </ul> 902 */ 903 public JsonReader newJsonReader(Reader reader) { 904 JsonReader jsonReader = new JsonReader(reader); 905 jsonReader.setLenient(lenient); 906 return jsonReader; 907 } 908 909 /** 910 * Writes the JSON for {@code jsonElement} to {@code writer}. 911 * 912 * <p>The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode}, 913 * regardless of the lenient mode setting of the provided writer. The lenient mode setting 914 * of the writer is restored once this method returns. 915 * 916 * <p>The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance 917 * (configured by the {@link GsonBuilder}) are applied, and the original settings of the 918 * writer are restored once this method returns. 919 * 920 * @throws JsonIOException if there was a problem writing to the writer 921 */ 922 public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException { 923 boolean oldLenient = writer.isLenient(); 924 writer.setLenient(true); 925 boolean oldHtmlSafe = writer.isHtmlSafe(); 926 writer.setHtmlSafe(htmlSafe); 927 boolean oldSerializeNulls = writer.getSerializeNulls(); 928 writer.setSerializeNulls(serializeNulls); 929 try { 930 Streams.write(jsonElement, writer); 931 } catch (IOException e) { 932 throw new JsonIOException(e); 933 } catch (AssertionError e) { 934 AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage()); 935 error.initCause(e); 936 throw error; 937 } finally { 938 writer.setLenient(oldLenient); 939 writer.setHtmlSafe(oldHtmlSafe); 940 writer.setSerializeNulls(oldSerializeNulls); 941 } 942 } 943 944 /** 945 * This method deserializes the specified JSON into an object of the specified class. It is not 946 * suitable to use if the specified class is a generic type since it will not have the generic 947 * type information because of the Type Erasure feature of Java. Therefore, this method should not 948 * be used if the desired type is a generic type. Note that this method works fine if the any of 949 * the fields of the specified object are generics, just the object itself should not be a 950 * generic type. For the cases when the object is of generic type, invoke 951 * {@link #fromJson(String, TypeToken)}. If you have the JSON in a {@link Reader} instead of 952 * a String, use {@link #fromJson(Reader, Class)} instead. 953 * 954 * <p>An exception is thrown if the JSON string has multiple top-level JSON elements, or if there 955 * is trailing data. Use {@link #fromJson(JsonReader, Type)} if this behavior is not desired. 956 * 957 * @param <T> the type of the desired object 958 * @param json the string from which the object is to be deserialized 959 * @param classOfT the class of T 960 * @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null} 961 * or if {@code json} is empty. 962 * @throws JsonSyntaxException if json is not a valid representation for an object of type 963 * classOfT 964 * 965 * @see #fromJson(Reader, Class) 966 * @see #fromJson(String, TypeToken) 967 */ 968 public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException { 969 T object = fromJson(json, TypeToken.get(classOfT)); 970 return Primitives.wrap(classOfT).cast(object); 971 } 972 973 /** 974 * This method deserializes the specified JSON into an object of the specified type. This method 975 * is useful if the specified object is a generic type. For non-generic objects, use 976 * {@link #fromJson(String, Class)} instead. If you have the JSON in a {@link Reader} instead of 977 * a String, use {@link #fromJson(Reader, Type)} instead. 978 * 979 * <p>Since {@code Type} is not parameterized by T, this method is not type-safe and 980 * should be used carefully. If you are creating the {@code Type} from a {@link TypeToken}, 981 * prefer using {@link #fromJson(String, TypeToken)} instead since its return type is based 982 * on the {@code TypeToken} and is therefore more type-safe. 983 * 984 * <p>An exception is thrown if the JSON string has multiple top-level JSON elements, 985 * or if there is trailing data. Use {@link #fromJson(JsonReader, Type)} if this behavior is 986 * not desired. 987 * 988 * @param <T> the type of the desired object 989 * @param json the string from which the object is to be deserialized 990 * @param typeOfT The specific genericized type of src 991 * @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null} 992 * or if {@code json} is empty. 993 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 994 * 995 * @see #fromJson(Reader, Type) 996 * @see #fromJson(String, Class) 997 * @see #fromJson(String, TypeToken) 998 */ 999 @SuppressWarnings("unchecked") 1000 public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException { 1001 return (T) fromJson(json, TypeToken.get(typeOfT)); 1002 } 1003 1004 /** 1005 * This method deserializes the specified JSON into an object of the specified type. This method 1006 * is useful if the specified object is a generic type. For non-generic objects, use 1007 * {@link #fromJson(String, Class)} instead. If you have the JSON in a {@link Reader} instead of 1008 * a String, use {@link #fromJson(Reader, TypeToken)} instead. 1009 * 1010 * <p>An exception is thrown if the JSON string has multiple top-level JSON elements, or if there 1011 * is trailing data. Use {@link #fromJson(JsonReader, TypeToken)} if this behavior is not desired. 1012 * 1013 * @param <T> the type of the desired object 1014 * @param json the string from which the object is to be deserialized 1015 * @param typeOfT The specific genericized type of src. You should create an anonymous subclass of 1016 * {@code TypeToken} with the specific generic type arguments. For example, to get the type for 1017 * {@code Collection<Foo>}, you should use: 1018 * <pre> 1019 * new TypeToken<Collection<Foo>>(){} 1020 * </pre> 1021 * @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null} 1022 * or if {@code json} is empty. 1023 * @throws JsonSyntaxException if json is not a valid representation for an object of the type typeOfT 1024 * 1025 * @see #fromJson(Reader, TypeToken) 1026 * @see #fromJson(String, Class) 1027 * @since 2.10 1028 */ 1029 public <T> T fromJson(String json, TypeToken<T> typeOfT) throws JsonSyntaxException { 1030 if (json == null) { 1031 return null; 1032 } 1033 StringReader reader = new StringReader(json); 1034 return fromJson(reader, typeOfT); 1035 } 1036 1037 /** 1038 * This method deserializes the JSON read from the specified reader into an object of the 1039 * specified class. It is not suitable to use if the specified class is a generic type since it 1040 * will not have the generic type information because of the Type Erasure feature of Java. 1041 * Therefore, this method should not be used if the desired type is a generic type. Note that 1042 * this method works fine if any of the fields of the specified object are generics, just the 1043 * object itself should not be a generic type. For the cases when the object is of generic type, 1044 * invoke {@link #fromJson(Reader, TypeToken)}. If you have the JSON in a String form instead of a 1045 * {@link Reader}, use {@link #fromJson(String, Class)} instead. 1046 * 1047 * <p>An exception is thrown if the JSON data has multiple top-level JSON elements, or if there 1048 * is trailing data. Use {@link #fromJson(JsonReader, Type)} if this behavior is not desired. 1049 * 1050 * @param <T> the type of the desired object 1051 * @param json the reader producing the JSON from which the object is to be deserialized. 1052 * @param classOfT the class of T 1053 * @return an object of type T from the Reader. Returns {@code null} if {@code json} is at EOF. 1054 * @throws JsonIOException if there was a problem reading from the Reader 1055 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1056 * @since 1.2 1057 * 1058 * @see #fromJson(String, Class) 1059 * @see #fromJson(Reader, TypeToken) 1060 */ 1061 public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException { 1062 T object = fromJson(json, TypeToken.get(classOfT)); 1063 return Primitives.wrap(classOfT).cast(object); 1064 } 1065 1066 /** 1067 * This method deserializes the JSON read from the specified reader into an object of the 1068 * specified type. This method is useful if the specified object is a generic type. For 1069 * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the JSON in a 1070 * String form instead of a {@link Reader}, use {@link #fromJson(String, Type)} instead. 1071 * 1072 * <p>Since {@code Type} is not parameterized by T, this method is not type-safe and 1073 * should be used carefully. If you are creating the {@code Type} from a {@link TypeToken}, 1074 * prefer using {@link #fromJson(Reader, TypeToken)} instead since its return type is based 1075 * on the {@code TypeToken} and is therefore more type-safe. 1076 * 1077 * <p>An exception is thrown if the JSON data has multiple top-level JSON elements, or if there 1078 * is trailing data. Use {@link #fromJson(JsonReader, Type)} if this behavior is not desired. 1079 * 1080 * @param <T> the type of the desired object 1081 * @param json the reader producing JSON from which the object is to be deserialized 1082 * @param typeOfT The specific genericized type of src 1083 * @return an object of type T from the Reader. Returns {@code null} if {@code json} is at EOF. 1084 * @throws JsonIOException if there was a problem reading from the Reader 1085 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1086 * @since 1.2 1087 * 1088 * @see #fromJson(String, Type) 1089 * @see #fromJson(Reader, Class) 1090 * @see #fromJson(Reader, TypeToken) 1091 */ 1092 @SuppressWarnings("unchecked") 1093 public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException { 1094 return (T) fromJson(json, TypeToken.get(typeOfT)); 1095 } 1096 1097 /** 1098 * This method deserializes the JSON read from the specified reader into an object of the 1099 * specified type. This method is useful if the specified object is a generic type. For 1100 * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the JSON in a 1101 * String form instead of a {@link Reader}, use {@link #fromJson(String, TypeToken)} instead. 1102 * 1103 * <p>An exception is thrown if the JSON data has multiple top-level JSON elements, or if there 1104 * is trailing data. Use {@link #fromJson(JsonReader, TypeToken)} if this behavior is not desired. 1105 * 1106 * @param <T> the type of the desired object 1107 * @param json the reader producing JSON from which the object is to be deserialized 1108 * @param typeOfT The specific genericized type of src. You should create an anonymous subclass of 1109 * {@code TypeToken} with the specific generic type arguments. For example, to get the type for 1110 * {@code Collection<Foo>}, you should use: 1111 * <pre> 1112 * new TypeToken<Collection<Foo>>(){} 1113 * </pre> 1114 * @return an object of type T from the Reader. Returns {@code null} if {@code json} is at EOF. 1115 * @throws JsonIOException if there was a problem reading from the Reader 1116 * @throws JsonSyntaxException if json is not a valid representation for an object of type of typeOfT 1117 * 1118 * @see #fromJson(String, TypeToken) 1119 * @see #fromJson(Reader, Class) 1120 * @since 2.10 1121 */ 1122 public <T> T fromJson(Reader json, TypeToken<T> typeOfT) throws JsonIOException, JsonSyntaxException { 1123 JsonReader jsonReader = newJsonReader(json); 1124 T object = fromJson(jsonReader, typeOfT); 1125 assertFullConsumption(object, jsonReader); 1126 return object; 1127 } 1128 1129 private static void assertFullConsumption(Object obj, JsonReader reader) { 1130 try { 1131 if (obj != null && reader.peek() != JsonToken.END_DOCUMENT) { 1132 throw new JsonSyntaxException("JSON document was not fully consumed."); 1133 } 1134 } catch (MalformedJsonException e) { 1135 throw new JsonSyntaxException(e); 1136 } catch (IOException e) { 1137 throw new JsonIOException(e); 1138 } 1139 } 1140 1141 // fromJson(JsonReader, Class) is unfortunately missing and cannot be added now without breaking 1142 // source compatibility in certain cases, see https://github.com/google/gson/pull/1700#discussion_r973764414 1143 1144 /** 1145 * Reads the next JSON value from {@code reader} and converts it to an object 1146 * of type {@code typeOfT}. Returns {@code null}, if the {@code reader} is at EOF. 1147 * 1148 * <p>Since {@code Type} is not parameterized by T, this method is not type-safe and 1149 * should be used carefully. If you are creating the {@code Type} from a {@link TypeToken}, 1150 * prefer using {@link #fromJson(JsonReader, TypeToken)} instead since its return type is based 1151 * on the {@code TypeToken} and is therefore more type-safe. If the provided type is a 1152 * {@code Class} the {@code TypeToken} can be created with {@link TypeToken#get(Class)}. 1153 * 1154 * <p>Unlike the other {@code fromJson} methods, no exception is thrown if the JSON data has 1155 * multiple top-level JSON elements, or if there is trailing data. 1156 * 1157 * <p>The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode}, 1158 * regardless of the lenient mode setting of the provided reader. The lenient mode setting 1159 * of the reader is restored once this method returns. 1160 * 1161 * @param <T> the type of the desired object 1162 * @param reader the reader whose next JSON value should be deserialized 1163 * @param typeOfT The specific genericized type of src 1164 * @return an object of type T from the JsonReader. Returns {@code null} if {@code reader} is at EOF. 1165 * @throws JsonIOException if there was a problem reading from the JsonReader 1166 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1167 * 1168 * @see #fromJson(Reader, Type) 1169 * @see #fromJson(JsonReader, TypeToken) 1170 */ 1171 @SuppressWarnings("unchecked") 1172 public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException { 1173 return (T) fromJson(reader, TypeToken.get(typeOfT)); 1174 } 1175 1176 /** 1177 * Reads the next JSON value from {@code reader} and converts it to an object 1178 * of type {@code typeOfT}. Returns {@code null}, if the {@code reader} is at EOF. 1179 * This method is useful if the specified object is a generic type. For non-generic objects, 1180 * {@link #fromJson(JsonReader, Type)} can be called, or {@link TypeToken#get(Class)} can 1181 * be used to create the type token. 1182 * 1183 * <p>Unlike the other {@code fromJson} methods, no exception is thrown if the JSON data has 1184 * multiple top-level JSON elements, or if there is trailing data. 1185 * 1186 * <p>The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode}, 1187 * regardless of the lenient mode setting of the provided reader. The lenient mode setting 1188 * of the reader is restored once this method returns. 1189 * 1190 * @param <T> the type of the desired object 1191 * @param reader the reader whose next JSON value should be deserialized 1192 * @param typeOfT The specific genericized type of src. You should create an anonymous subclass of 1193 * {@code TypeToken} with the specific generic type arguments. For example, to get the type for 1194 * {@code Collection<Foo>}, you should use: 1195 * <pre> 1196 * new TypeToken<Collection<Foo>>(){} 1197 * </pre> 1198 * @return an object of type T from the JsonReader. Returns {@code null} if {@code reader} is at EOF. 1199 * @throws JsonIOException if there was a problem reading from the JsonReader 1200 * @throws JsonSyntaxException if json is not a valid representation for an object of the type typeOfT 1201 * 1202 * @see #fromJson(Reader, TypeToken) 1203 * @see #fromJson(JsonReader, Type) 1204 * @since 2.10 1205 */ 1206 public <T> T fromJson(JsonReader reader, TypeToken<T> typeOfT) throws JsonIOException, JsonSyntaxException { 1207 boolean isEmpty = true; 1208 boolean oldLenient = reader.isLenient(); 1209 reader.setLenient(true); 1210 try { 1211 reader.peek(); 1212 isEmpty = false; 1213 TypeAdapter<T> typeAdapter = getAdapter(typeOfT); 1214 T object = typeAdapter.read(reader); 1215 return object; 1216 } catch (EOFException e) { 1217 /* 1218 * For compatibility with JSON 1.5 and earlier, we return null for empty 1219 * documents instead of throwing. 1220 */ 1221 if (isEmpty) { 1222 return null; 1223 } 1224 throw new JsonSyntaxException(e); 1225 } catch (IllegalStateException e) { 1226 throw new JsonSyntaxException(e); 1227 } catch (IOException e) { 1228 // TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException 1229 throw new JsonSyntaxException(e); 1230 } catch (AssertionError e) { 1231 AssertionError error = new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage()); 1232 error.initCause(e); 1233 throw error; 1234 } finally { 1235 reader.setLenient(oldLenient); 1236 } 1237 } 1238 1239 /** 1240 * This method deserializes the JSON read from the specified parse tree into an object of the 1241 * specified type. It is not suitable to use if the specified class is a generic type since it 1242 * will not have the generic type information because of the Type Erasure feature of Java. 1243 * Therefore, this method should not be used if the desired type is a generic type. Note that 1244 * this method works fine if any of the fields of the specified object are generics, just the 1245 * object itself should not be a generic type. For the cases when the object is of generic type, 1246 * invoke {@link #fromJson(JsonElement, TypeToken)}. 1247 * 1248 * @param <T> the type of the desired object 1249 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to 1250 * be deserialized 1251 * @param classOfT The class of T 1252 * @return an object of type T from the JSON. Returns {@code null} if {@code json} is {@code null} 1253 * or if {@code json} is empty. 1254 * @throws JsonSyntaxException if json is not a valid representation for an object of type classOfT 1255 * @since 1.3 1256 * 1257 * @see #fromJson(Reader, Class) 1258 * @see #fromJson(JsonElement, TypeToken) 1259 */ 1260 public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException { 1261 T object = fromJson(json, TypeToken.get(classOfT)); 1262 return Primitives.wrap(classOfT).cast(object); 1263 } 1264 1265 /** 1266 * This method deserializes the JSON read from the specified parse tree into an object of the 1267 * specified type. This method is useful if the specified object is a generic type. For 1268 * non-generic objects, use {@link #fromJson(JsonElement, Class)} instead. 1269 * 1270 * <p>Since {@code Type} is not parameterized by T, this method is not type-safe and 1271 * should be used carefully. If you are creating the {@code Type} from a {@link TypeToken}, 1272 * prefer using {@link #fromJson(JsonElement, TypeToken)} instead since its return type is based 1273 * on the {@code TypeToken} and is therefore more type-safe. 1274 * 1275 * @param <T> the type of the desired object 1276 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to 1277 * be deserialized 1278 * @param typeOfT The specific genericized type of src 1279 * @return an object of type T from the JSON. Returns {@code null} if {@code json} is {@code null} 1280 * or if {@code json} is empty. 1281 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1282 * @since 1.3 1283 * 1284 * @see #fromJson(Reader, Type) 1285 * @see #fromJson(JsonElement, Class) 1286 * @see #fromJson(JsonElement, TypeToken) 1287 */ 1288 @SuppressWarnings("unchecked") 1289 public <T> T fromJson(JsonElement json, Type typeOfT) throws JsonSyntaxException { 1290 return (T) fromJson(json, TypeToken.get(typeOfT)); 1291 } 1292 1293 /** 1294 * This method deserializes the JSON read from the specified parse tree into an object of the 1295 * specified type. This method is useful if the specified object is a generic type. For 1296 * non-generic objects, use {@link #fromJson(JsonElement, Class)} instead. 1297 * 1298 * @param <T> the type of the desired object 1299 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to 1300 * be deserialized 1301 * @param typeOfT The specific genericized type of src. You should create an anonymous subclass of 1302 * {@code TypeToken} with the specific generic type arguments. For example, to get the type for 1303 * {@code Collection<Foo>}, you should use: 1304 * <pre> 1305 * new TypeToken<Collection<Foo>>(){} 1306 * </pre> 1307 * @return an object of type T from the JSON. Returns {@code null} if {@code json} is {@code null} 1308 * or if {@code json} is empty. 1309 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1310 * 1311 * @see #fromJson(Reader, TypeToken) 1312 * @see #fromJson(JsonElement, Class) 1313 * @since 2.10 1314 */ 1315 public <T> T fromJson(JsonElement json, TypeToken<T> typeOfT) throws JsonSyntaxException { 1316 if (json == null) { 1317 return null; 1318 } 1319 return fromJson(new JsonTreeReader(json), typeOfT); 1320 } 1321 1322 static class FutureTypeAdapter<T> extends SerializationDelegatingTypeAdapter<T> { 1323 private TypeAdapter<T> delegate; 1324 1325 public void setDelegate(TypeAdapter<T> typeAdapter) { 1326 if (delegate != null) { 1327 throw new AssertionError(); 1328 } 1329 delegate = typeAdapter; 1330 } 1331 1332 private TypeAdapter<T> delegate() { 1333 if (delegate == null) { 1334 throw new IllegalStateException("Delegate has not been set yet"); 1335 } 1336 return delegate; 1337 } 1338 1339 @Override public TypeAdapter<T> getSerializationDelegate() { 1340 return delegate(); 1341 } 1342 1343 @Override public T read(JsonReader in) throws IOException { 1344 return delegate().read(in); 1345 } 1346 1347 @Override public void write(JsonWriter out, T value) throws IOException { 1348 delegate().write(out, value); 1349 } 1350 } 1351 1352 @Override 1353 public String toString() { 1354 return new StringBuilder("{serializeNulls:") 1355 .append(serializeNulls) 1356 .append(",factories:").append(factories) 1357 .append(",instanceCreators:").append(constructorConstructor) 1358 .append("}") 1359 .toString(); 1360 } 1361 } 1362