2 * Copyright (C) 2008 Google Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com
.google
.gson
;
19 import com
.google
.gson
.internal
.ConstructorConstructor
;
20 import com
.google
.gson
.internal
.Excluder
;
21 import com
.google
.gson
.internal
.Primitives
;
22 import com
.google
.gson
.internal
.Streams
;
23 import com
.google
.gson
.internal
.bind
.ArrayTypeAdapter
;
24 import com
.google
.gson
.internal
.bind
.CollectionTypeAdapterFactory
;
25 import com
.google
.gson
.internal
.bind
.DateTypeAdapter
;
26 import com
.google
.gson
.internal
.bind
.JsonTreeReader
;
27 import com
.google
.gson
.internal
.bind
.JsonTreeWriter
;
28 import com
.google
.gson
.internal
.bind
.MapTypeAdapterFactory
;
29 import com
.google
.gson
.internal
.bind
.ObjectTypeAdapter
;
30 import com
.google
.gson
.internal
.bind
.ReflectiveTypeAdapterFactory
;
31 import com
.google
.gson
.internal
.bind
.SqlDateTypeAdapter
;
32 import com
.google
.gson
.internal
.bind
.TimeTypeAdapter
;
33 import com
.google
.gson
.internal
.bind
.TypeAdapters
;
34 import com
.google
.gson
.reflect
.TypeToken
;
35 import com
.google
.gson
.stream
.JsonReader
;
36 import com
.google
.gson
.stream
.JsonToken
;
37 import com
.google
.gson
.stream
.JsonWriter
;
38 import com
.google
.gson
.stream
.MalformedJsonException
;
39 import java
.io
.EOFException
;
40 import java
.io
.IOException
;
41 import java
.io
.Reader
;
42 import java
.io
.StringReader
;
43 import java
.io
.StringWriter
;
44 import java
.io
.Writer
;
45 import java
.lang
.reflect
.Type
;
46 import java
.math
.BigDecimal
;
47 import java
.math
.BigInteger
;
48 import java
.util
.ArrayList
;
49 import java
.util
.Collections
;
50 import java
.util
.HashMap
;
51 import java
.util
.List
;
55 * This is the main class for using Gson. Gson is typically used by first constructing a
56 * Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)}
59 * <p>You can create a Gson instance by invoking {@code new Gson()} if the default configuration
60 * is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various
61 * configuration options such as versioning support, pretty printing, custom
62 * {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.</p>
64 * <p>Here is an example of how Gson is used for a simple Class:
67 * Gson gson = new Gson(); // Or use new GsonBuilder().create();
68 * MyType target = new MyType();
69 * String json = gson.toJson(target); // serializes target to Json
70 * MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2
73 * <p>If the object that your are serializing/deserializing is a {@code ParameterizedType}
74 * (i.e. contains at least one type parameter and may be an array) then you must use the
75 * {@link #toJson(Object, Type)} or {@link #fromJson(String, Type)} method. Here is an
76 * example for serializing and deserialing a {@code ParameterizedType}:
79 * Type listType = new TypeToken<List<String>>() {}.getType();
80 * List<String> target = new LinkedList<String>();
83 * Gson gson = new Gson();
84 * String json = gson.toJson(target, listType);
85 * List<String> target2 = gson.fromJson(json, listType);
88 * <p>See the <a href="https://sites.google.com/site/gson/gson-user-guide">Gson User Guide</a>
89 * for a more complete set of examples.</p>
91 * @see com.google.gson.reflect.TypeToken
93 * @author Inderjeet Singh
95 * @author Jesse Wilson
97 public final class Gson
{
98 static final boolean DEFAULT_JSON_NON_EXECUTABLE
= false;
100 private static final String JSON_NON_EXECUTABLE_PREFIX
= ")]}'\n";
103 * This thread local guards against reentrant calls to getAdapter(). In
104 * certain object graphs, creating an adapter for a type may recursively
105 * require an adapter for the same type! Without intervention, the recursive
106 * lookup would stack overflow. We cheat by returning a proxy type adapter.
107 * The proxy is wired up once the initial adapter has been created.
109 private final ThreadLocal
<Map
<TypeToken
<?
>, FutureTypeAdapter
<?
>>> calls
110 = new ThreadLocal
<Map
<TypeToken
<?
>, FutureTypeAdapter
<?
>>>();
112 private final Map
<TypeToken
<?
>, TypeAdapter
<?
>> typeTokenCache
113 = Collections
.synchronizedMap(new HashMap
<TypeToken
<?
>, TypeAdapter
<?
>>());
115 private final List
<TypeAdapterFactory
> factories
;
116 private final ConstructorConstructor constructorConstructor
;
118 private final boolean serializeNulls
;
119 private final boolean htmlSafe
;
120 private final boolean generateNonExecutableJson
;
121 private final boolean prettyPrinting
;
123 final JsonDeserializationContext deserializationContext
= new JsonDeserializationContext() {
124 @SuppressWarnings("unchecked")
125 public <T
> T
deserialize(JsonElement json
, Type typeOfT
) throws JsonParseException
{
126 return (T
) fromJson(json
, typeOfT
);
130 final JsonSerializationContext serializationContext
= new JsonSerializationContext() {
131 public JsonElement
serialize(Object src
) {
132 return toJsonTree(src
);
134 public JsonElement
serialize(Object src
, Type typeOfSrc
) {
135 return toJsonTree(src
, typeOfSrc
);
140 * Constructs a Gson object with default configuration. The default configuration has the
141 * following settings:
143 * <li>The JSON generated by <code>toJson</code> methods is in compact representation. This
144 * means that all the unneeded white-space is removed. You can change this behavior with
145 * {@link GsonBuilder#setPrettyPrinting()}. </li>
146 * <li>The generated JSON omits all the fields that are null. Note that nulls in arrays are
147 * kept as is since an array is an ordered list. Moreover, if a field is not null, but its
148 * generated JSON is empty, the field is kept. You can configure Gson to serialize null values
149 * by setting {@link GsonBuilder#serializeNulls()}.</li>
150 * <li>Gson provides default serialization and deserialization for Enums, {@link Map},
151 * {@link java.net.URL}, {@link java.net.URI}, {@link java.util.Locale}, {@link java.util.Date},
152 * {@link java.math.BigDecimal}, and {@link java.math.BigInteger} classes. If you would prefer
153 * to change the default representation, you can do so by registering a type adapter through
154 * {@link GsonBuilder#registerTypeAdapter(Type, Object)}. </li>
155 * <li>The default Date format is same as {@link java.text.DateFormat#DEFAULT}. This format
156 * ignores the millisecond portion of the date during serialization. You can change
157 * this by invoking {@link GsonBuilder#setDateFormat(int)} or
158 * {@link GsonBuilder#setDateFormat(String)}. </li>
159 * <li>By default, Gson ignores the {@link com.google.gson.annotations.Expose} annotation.
160 * You can enable Gson to serialize/deserialize only those fields marked with this annotation
161 * through {@link GsonBuilder#excludeFieldsWithoutExposeAnnotation()}. </li>
162 * <li>By default, Gson ignores the {@link com.google.gson.annotations.Since} annotation. You
163 * can enable Gson to use this annotation through {@link GsonBuilder#setVersion(double)}.</li>
164 * <li>The default field naming policy for the output Json is same as in Java. So, a Java class
165 * field <code>versionNumber</code> will be output as <code>"versionNumber@quot;</code> in
166 * Json. The same rules are applied for mapping incoming Json to the Java classes. You can
167 * change this policy through {@link GsonBuilder#setFieldNamingPolicy(FieldNamingPolicy)}.</li>
168 * <li>By default, Gson excludes <code>transient</code> or <code>static</code> fields from
169 * consideration for serialization and deserialization. You can change this behavior through
170 * {@link GsonBuilder#excludeFieldsWithModifiers(int...)}.</li>
174 this(Excluder
.DEFAULT
, FieldNamingPolicy
.IDENTITY
,
175 Collections
.<Type
, InstanceCreator
<?
>>emptyMap(), false, false, DEFAULT_JSON_NON_EXECUTABLE
,
176 true, false, false, LongSerializationPolicy
.DEFAULT
,
177 Collections
.<TypeAdapterFactory
>emptyList());
180 Gson(final Excluder excluder
, final FieldNamingStrategy fieldNamingPolicy
,
181 final Map
<Type
, InstanceCreator
<?
>> instanceCreators
, boolean serializeNulls
,
182 boolean complexMapKeySerialization
, boolean generateNonExecutableGson
, boolean htmlSafe
,
183 boolean prettyPrinting
, boolean serializeSpecialFloatingPointValues
,
184 LongSerializationPolicy longSerializationPolicy
,
185 List
<TypeAdapterFactory
> typeAdapterFactories
) {
186 this.constructorConstructor
= new ConstructorConstructor(instanceCreators
);
187 this.serializeNulls
= serializeNulls
;
188 this.generateNonExecutableJson
= generateNonExecutableGson
;
189 this.htmlSafe
= htmlSafe
;
190 this.prettyPrinting
= prettyPrinting
;
192 List
<TypeAdapterFactory
> factories
= new ArrayList
<TypeAdapterFactory
>();
194 // built-in type adapters that cannot be overridden
195 factories
.add(TypeAdapters
.JSON_ELEMENT_FACTORY
);
196 factories
.add(ObjectTypeAdapter
.FACTORY
);
198 // the excluder must precede all adapters that handle user-defined types
199 factories
.add(excluder
);
201 // user's type adapters
202 factories
.addAll(typeAdapterFactories
);
204 // type adapters for basic platform types
205 factories
.add(TypeAdapters
.STRING_FACTORY
);
206 factories
.add(TypeAdapters
.INTEGER_FACTORY
);
207 factories
.add(TypeAdapters
.BOOLEAN_FACTORY
);
208 factories
.add(TypeAdapters
.BYTE_FACTORY
);
209 factories
.add(TypeAdapters
.SHORT_FACTORY
);
210 factories
.add(TypeAdapters
.newFactory(long.class, Long
.class,
211 longAdapter(longSerializationPolicy
)));
212 factories
.add(TypeAdapters
.newFactory(double.class, Double
.class,
213 doubleAdapter(serializeSpecialFloatingPointValues
)));
214 factories
.add(TypeAdapters
.newFactory(float.class, Float
.class,
215 floatAdapter(serializeSpecialFloatingPointValues
)));
216 factories
.add(TypeAdapters
.NUMBER_FACTORY
);
217 factories
.add(TypeAdapters
.CHARACTER_FACTORY
);
218 factories
.add(TypeAdapters
.STRING_BUILDER_FACTORY
);
219 factories
.add(TypeAdapters
.STRING_BUFFER_FACTORY
);
220 factories
.add(TypeAdapters
.newFactory(BigDecimal
.class, TypeAdapters
.BIG_DECIMAL
));
221 factories
.add(TypeAdapters
.newFactory(BigInteger
.class, TypeAdapters
.BIG_INTEGER
));
222 factories
.add(TypeAdapters
.URL_FACTORY
);
223 factories
.add(TypeAdapters
.URI_FACTORY
);
224 factories
.add(TypeAdapters
.UUID_FACTORY
);
225 factories
.add(TypeAdapters
.LOCALE_FACTORY
);
226 factories
.add(TypeAdapters
.INET_ADDRESS_FACTORY
);
227 factories
.add(TypeAdapters
.BIT_SET_FACTORY
);
228 factories
.add(DateTypeAdapter
.FACTORY
);
229 factories
.add(TypeAdapters
.CALENDAR_FACTORY
);
230 factories
.add(TimeTypeAdapter
.FACTORY
);
231 factories
.add(SqlDateTypeAdapter
.FACTORY
);
232 factories
.add(TypeAdapters
.TIMESTAMP_FACTORY
);
233 factories
.add(ArrayTypeAdapter
.FACTORY
);
234 factories
.add(TypeAdapters
.ENUM_FACTORY
);
235 factories
.add(TypeAdapters
.CLASS_FACTORY
);
237 // type adapters for composite and user-defined types
238 factories
.add(new CollectionTypeAdapterFactory(constructorConstructor
));
239 factories
.add(new MapTypeAdapterFactory(constructorConstructor
, complexMapKeySerialization
));
240 factories
.add(new ReflectiveTypeAdapterFactory(
241 constructorConstructor
, fieldNamingPolicy
, excluder
));
243 this.factories
= Collections
.unmodifiableList(factories
);
246 private TypeAdapter
<Number
> doubleAdapter(boolean serializeSpecialFloatingPointValues
) {
247 if (serializeSpecialFloatingPointValues
) {
248 return TypeAdapters
.DOUBLE
;
250 return new TypeAdapter
<Number
>() {
251 @Override public Double
read(JsonReader in
) throws IOException
{
252 if (in
.peek() == JsonToken
.NULL
) {
256 return in
.nextDouble();
258 @Override public void write(JsonWriter out
, Number value
) throws IOException
{
263 double doubleValue
= value
.doubleValue();
264 checkValidFloatingPoint(doubleValue
);
270 private TypeAdapter
<Number
> floatAdapter(boolean serializeSpecialFloatingPointValues
) {
271 if (serializeSpecialFloatingPointValues
) {
272 return TypeAdapters
.FLOAT
;
274 return new TypeAdapter
<Number
>() {
275 @Override public Float
read(JsonReader in
) throws IOException
{
276 if (in
.peek() == JsonToken
.NULL
) {
280 return (float) in
.nextDouble();
282 @Override public void write(JsonWriter out
, Number value
) throws IOException
{
287 float floatValue
= value
.floatValue();
288 checkValidFloatingPoint(floatValue
);
294 private void checkValidFloatingPoint(double value
) {
295 if (Double
.isNaN(value
) || Double
.isInfinite(value
)) {
296 throw new IllegalArgumentException(value
297 + " is not a valid double value as per JSON specification. To override this"
298 + " behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.");
302 private TypeAdapter
<Number
> longAdapter(LongSerializationPolicy longSerializationPolicy
) {
303 if (longSerializationPolicy
== LongSerializationPolicy
.DEFAULT
) {
304 return TypeAdapters
.LONG
;
306 return new TypeAdapter
<Number
>() {
307 @Override public Number
read(JsonReader in
) throws IOException
{
308 if (in
.peek() == JsonToken
.NULL
) {
312 return in
.nextLong();
314 @Override public void write(JsonWriter out
, Number value
) throws IOException
{
319 out
.value(value
.toString());
325 * Returns the type adapter for {@code} type.
327 * @throws IllegalArgumentException if this GSON cannot serialize and
328 * deserialize {@code type}.
330 @SuppressWarnings("unchecked")
331 public <T
> TypeAdapter
<T
> getAdapter(TypeToken
<T
> type
) {
332 TypeAdapter
<?
> cached
= typeTokenCache
.get(type
);
333 if (cached
!= null) {
334 return (TypeAdapter
<T
>) cached
;
337 Map
<TypeToken
<?
>, FutureTypeAdapter
<?
>> threadCalls
= calls
.get();
338 boolean requiresThreadLocalCleanup
= false;
339 if (threadCalls
== null) {
340 threadCalls
= new HashMap
<TypeToken
<?
>, FutureTypeAdapter
<?
>>();
341 calls
.set(threadCalls
);
342 requiresThreadLocalCleanup
= true;
345 // the key and value type parameters always agree
346 FutureTypeAdapter
<T
> ongoingCall
= (FutureTypeAdapter
<T
>) threadCalls
.get(type
);
347 if (ongoingCall
!= null) {
352 FutureTypeAdapter
<T
> call
= new FutureTypeAdapter
<T
>();
353 threadCalls
.put(type
, call
);
355 for (TypeAdapterFactory factory
: factories
) {
356 TypeAdapter
<T
> candidate
= factory
.create(this, type
);
357 if (candidate
!= null) {
358 call
.setDelegate(candidate
);
359 typeTokenCache
.put(type
, candidate
);
363 throw new IllegalArgumentException("GSON cannot handle " + type
);
365 threadCalls
.remove(type
);
367 if (requiresThreadLocalCleanup
) {
374 * This method is used to get an alternate type adapter for the specified type. This is used
375 * to access a type adapter that is overridden by a {@link TypeAdapterFactory} that you
376 * may have registered. This features is typically used when you want to register a type
377 * adapter that does a little bit of work but then delegates further processing to the Gson
378 * default type adapter. Here is an example:
379 * <p>Let's say we want to write a type adapter that counts the number of objects being read
380 * from or written to JSON. We can achieve this by writing a type adapter factory that uses
381 * the <code>getDelegateAdapter</code> method:
383 * class StatsTypeAdapterFactory implements TypeAdapterFactory {
384 * public int numReads = 0;
385 * public int numWrites = 0;
386 * public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
387 * final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
388 * return new TypeAdapter<T>() {
389 * public void write(JsonWriter out, T value) throws IOException {
391 * delegate.write(out, value);
393 * public T read(JsonReader in) throws IOException {
395 * return delegate.read(in);
401 * This factory can now be used like this:
403 * StatsTypeAdapterFactory stats = new StatsTypeAdapterFactory();
404 * Gson gson = new GsonBuilder().registerTypeAdapterFactory(stats).create();
405 * // Call gson.toJson() and fromJson methods on objects
406 * System.out.println("Num JSON reads" + stats.numReads);
407 * System.out.println("Num JSON writes" + stats.numWrites);
409 * Note that since you can not override type adapter factories for String and Java primitive
410 * types, our stats factory will not count the number of String or primitives that will be
412 * @param skipPast The type adapter factory that needs to be skipped while searching for
413 * a matching type adapter. In most cases, you should just pass <i>this</i> (the type adapter
414 * factory from where {@link #getDelegateAdapter} method is being invoked).
415 * @param type Type for which the delegate adapter is being searched for.
419 public <T
> TypeAdapter
<T
> getDelegateAdapter(TypeAdapterFactory skipPast
, TypeToken
<T
> type
) {
420 boolean skipPastFound
= false;
422 for (TypeAdapterFactory factory
: factories
) {
423 if (!skipPastFound
) {
424 if (factory
== skipPast
) {
425 skipPastFound
= true;
430 TypeAdapter
<T
> candidate
= factory
.create(this, type
);
431 if (candidate
!= null) {
435 throw new IllegalArgumentException("GSON cannot serialize " + type
);
439 * Returns the type adapter for {@code} type.
441 * @throws IllegalArgumentException if this GSON cannot serialize and
442 * deserialize {@code type}.
444 public <T
> TypeAdapter
<T
> getAdapter(Class
<T
> type
) {
445 return getAdapter(TypeToken
.get(type
));
449 * This method serializes the specified object into its equivalent representation as a tree of
450 * {@link JsonElement}s. This method should be used when the specified object is not a generic
451 * type. This method uses {@link Class#getClass()} to get the type for the specified object, but
452 * the {@code getClass()} loses the generic type information because of the Type Erasure feature
453 * of Java. Note that this method works fine if the any of the object fields are of generic type,
454 * just the object itself should not be of a generic type. If the object is of generic type, use
455 * {@link #toJsonTree(Object, Type)} instead.
457 * @param src the object for which Json representation is to be created setting for Gson
458 * @return Json representation of {@code src}.
461 public JsonElement
toJsonTree(Object src
) {
463 return JsonNull
.INSTANCE
;
465 return toJsonTree(src
, src
.getClass());
469 * This method serializes the specified object, including those of generic types, into its
470 * equivalent representation as a tree of {@link JsonElement}s. This method must be used if the
471 * specified object is a generic type. For non-generic objects, use {@link #toJsonTree(Object)}
474 * @param src the object for which JSON representation is to be created
475 * @param typeOfSrc The specific genericized type of src. You can obtain
476 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example,
477 * to get the type for {@code Collection<Foo>}, you should use:
479 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
481 * @return Json representation of {@code src}
484 public JsonElement
toJsonTree(Object src
, Type typeOfSrc
) {
485 JsonTreeWriter writer
= new JsonTreeWriter();
486 toJson(src
, typeOfSrc
, writer
);
491 * This method serializes the specified object into its equivalent Json representation.
492 * This method should be used when the specified object is not a generic type. This method uses
493 * {@link Class#getClass()} to get the type for the specified object, but the
494 * {@code getClass()} loses the generic type information because of the Type Erasure feature
495 * of Java. Note that this method works fine if the any of the object fields are of generic type,
496 * just the object itself should not be of a generic type. If the object is of generic type, use
497 * {@link #toJson(Object, Type)} instead. If you want to write out the object to a
498 * {@link Writer}, use {@link #toJson(Object, Appendable)} instead.
500 * @param src the object for which Json representation is to be created setting for Gson
501 * @return Json representation of {@code src}.
503 public String
toJson(Object src
) {
505 return toJson(JsonNull
.INSTANCE
);
507 return toJson(src
, src
.getClass());
511 * This method serializes the specified object, including those of generic types, into its
512 * equivalent Json representation. This method must be used if the specified object is a generic
513 * type. For non-generic objects, use {@link #toJson(Object)} instead. If you want to write out
514 * the object to a {@link Appendable}, use {@link #toJson(Object, Type, Appendable)} instead.
516 * @param src the object for which JSON representation is to be created
517 * @param typeOfSrc The specific genericized type of src. You can obtain
518 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example,
519 * to get the type for {@code Collection<Foo>}, you should use:
521 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
523 * @return Json representation of {@code src}
525 public String
toJson(Object src
, Type typeOfSrc
) {
526 StringWriter writer
= new StringWriter();
527 toJson(src
, typeOfSrc
, writer
);
528 return writer
.toString();
532 * This method serializes the specified object into its equivalent Json representation.
533 * This method should be used when the specified object is not a generic type. This method uses
534 * {@link Class#getClass()} to get the type for the specified object, but the
535 * {@code getClass()} loses the generic type information because of the Type Erasure feature
536 * of Java. Note that this method works fine if the any of the object fields are of generic type,
537 * just the object itself should not be of a generic type. If the object is of generic type, use
538 * {@link #toJson(Object, Type, Appendable)} instead.
540 * @param src the object for which Json representation is to be created setting for Gson
541 * @param writer Writer to which the Json representation needs to be written
542 * @throws JsonIOException if there was a problem writing to the writer
545 public void toJson(Object src
, Appendable writer
) throws JsonIOException
{
547 toJson(src
, src
.getClass(), writer
);
549 toJson(JsonNull
.INSTANCE
, writer
);
554 * This method serializes the specified object, including those of generic types, into its
555 * equivalent Json representation. This method must be used if the specified object is a generic
556 * type. For non-generic objects, use {@link #toJson(Object, Appendable)} instead.
558 * @param src the object for which JSON representation is to be created
559 * @param typeOfSrc The specific genericized type of src. You can obtain
560 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example,
561 * to get the type for {@code Collection<Foo>}, you should use:
563 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
565 * @param writer Writer to which the Json representation of src needs to be written.
566 * @throws JsonIOException if there was a problem writing to the writer
569 public void toJson(Object src
, Type typeOfSrc
, Appendable writer
) throws JsonIOException
{
571 JsonWriter jsonWriter
= newJsonWriter(Streams
.writerForAppendable(writer
));
572 toJson(src
, typeOfSrc
, jsonWriter
);
573 } catch (IOException e
) {
574 throw new JsonIOException(e
);
579 * Writes the JSON representation of {@code src} of type {@code typeOfSrc} to
581 * @throws JsonIOException if there was a problem writing to the writer
583 @SuppressWarnings("unchecked")
584 public void toJson(Object src
, Type typeOfSrc
, JsonWriter writer
) throws JsonIOException
{
585 TypeAdapter
<?
> adapter
= getAdapter(TypeToken
.get(typeOfSrc
));
586 boolean oldLenient
= writer
.isLenient();
587 writer
.setLenient(true);
588 boolean oldHtmlSafe
= writer
.isHtmlSafe();
589 writer
.setHtmlSafe(htmlSafe
);
590 boolean oldSerializeNulls
= writer
.getSerializeNulls();
591 writer
.setSerializeNulls(serializeNulls
);
593 ((TypeAdapter
<Object
>) adapter
).write(writer
, src
);
594 } catch (IOException e
) {
595 throw new JsonIOException(e
);
597 writer
.setLenient(oldLenient
);
598 writer
.setHtmlSafe(oldHtmlSafe
);
599 writer
.setSerializeNulls(oldSerializeNulls
);
604 * Converts a tree of {@link JsonElement}s into its equivalent JSON representation.
606 * @param jsonElement root of a tree of {@link JsonElement}s
607 * @return JSON String representation of the tree
610 public String
toJson(JsonElement jsonElement
) {
611 StringWriter writer
= new StringWriter();
612 toJson(jsonElement
, writer
);
613 return writer
.toString();
617 * Writes out the equivalent JSON for a tree of {@link JsonElement}s.
619 * @param jsonElement root of a tree of {@link JsonElement}s
620 * @param writer Writer to which the Json representation needs to be written
621 * @throws JsonIOException if there was a problem writing to the writer
624 public void toJson(JsonElement jsonElement
, Appendable writer
) throws JsonIOException
{
626 JsonWriter jsonWriter
= newJsonWriter(Streams
.writerForAppendable(writer
));
627 toJson(jsonElement
, jsonWriter
);
628 } catch (IOException e
) {
629 throw new RuntimeException(e
);
634 * Returns a new JSON writer configured for this GSON and with the non-execute
635 * prefix if that is configured.
637 private JsonWriter
newJsonWriter(Writer writer
) throws IOException
{
638 if (generateNonExecutableJson
) {
639 writer
.write(JSON_NON_EXECUTABLE_PREFIX
);
641 JsonWriter jsonWriter
= new JsonWriter(writer
);
642 if (prettyPrinting
) {
643 jsonWriter
.setIndent(" ");
645 jsonWriter
.setSerializeNulls(serializeNulls
);
650 * Writes the JSON for {@code jsonElement} to {@code writer}.
651 * @throws JsonIOException if there was a problem writing to the writer
653 public void toJson(JsonElement jsonElement
, JsonWriter writer
) throws JsonIOException
{
654 boolean oldLenient
= writer
.isLenient();
655 writer
.setLenient(true);
656 boolean oldHtmlSafe
= writer
.isHtmlSafe();
657 writer
.setHtmlSafe(htmlSafe
);
658 boolean oldSerializeNulls
= writer
.getSerializeNulls();
659 writer
.setSerializeNulls(serializeNulls
);
661 Streams
.write(jsonElement
, writer
);
662 } catch (IOException e
) {
663 throw new JsonIOException(e
);
665 writer
.setLenient(oldLenient
);
666 writer
.setHtmlSafe(oldHtmlSafe
);
667 writer
.setSerializeNulls(oldSerializeNulls
);
672 * This method deserializes the specified Json into an object of the specified class. It is not
673 * suitable to use if the specified class is a generic type since it will not have the generic
674 * type information because of the Type Erasure feature of Java. Therefore, this method should not
675 * be used if the desired type is a generic type. Note that this method works fine if the any of
676 * the fields of the specified object are generics, just the object itself should not be a
677 * generic type. For the cases when the object is of generic type, invoke
678 * {@link #fromJson(String, Type)}. If you have the Json in a {@link Reader} instead of
679 * a String, use {@link #fromJson(Reader, Class)} instead.
681 * @param <T> the type of the desired object
682 * @param json the string from which the object is to be deserialized
683 * @param classOfT the class of T
684 * @return an object of type T from the string
685 * @throws JsonSyntaxException if json is not a valid representation for an object of type
688 public <T
> T
fromJson(String json
, Class
<T
> classOfT
) throws JsonSyntaxException
{
689 Object object
= fromJson(json
, (Type
) classOfT
);
690 return Primitives
.wrap(classOfT
).cast(object
);
694 * This method deserializes the specified Json into an object of the specified type. This method
695 * is useful if the specified object is a generic type. For non-generic objects, use
696 * {@link #fromJson(String, Class)} instead. If you have the Json in a {@link Reader} instead of
697 * a String, use {@link #fromJson(Reader, Type)} instead.
699 * @param <T> the type of the desired object
700 * @param json the string from which the object is to be deserialized
701 * @param typeOfT The specific genericized type of src. You can obtain this type by using the
702 * {@link com.google.gson.reflect.TypeToken} class. For example, to get the type for
703 * {@code Collection<Foo>}, you should use:
705 * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
707 * @return an object of type T from the string
708 * @throws JsonParseException if json is not a valid representation for an object of type typeOfT
709 * @throws JsonSyntaxException if json is not a valid representation for an object of type
711 @SuppressWarnings("unchecked")
712 public <T
> T
fromJson(String json
, Type typeOfT
) throws JsonSyntaxException
{
716 StringReader reader
= new StringReader(json
);
717 T target
= (T
) fromJson(reader
, typeOfT
);
722 * This method deserializes the Json read from the specified reader into an object of the
723 * specified class. It is not suitable to use if the specified class is a generic type since it
724 * will not have the generic type information because of the Type Erasure feature of Java.
725 * Therefore, this method should not be used if the desired type is a generic type. Note that
726 * this method works fine if the any of the fields of the specified object are generics, just the
727 * object itself should not be a generic type. For the cases when the object is of generic type,
728 * invoke {@link #fromJson(Reader, Type)}. If you have the Json in a String form instead of a
729 * {@link Reader}, use {@link #fromJson(String, Class)} instead.
731 * @param <T> the type of the desired object
732 * @param json the reader producing the Json from which the object is to be deserialized.
733 * @param classOfT the class of T
734 * @return an object of type T from the string
735 * @throws JsonIOException if there was a problem reading from the Reader
736 * @throws JsonSyntaxException if json is not a valid representation for an object of type
739 public <T
> T
fromJson(Reader json
, Class
<T
> classOfT
) throws JsonSyntaxException
, JsonIOException
{
740 JsonReader jsonReader
= new JsonReader(json
);
741 Object object
= fromJson(jsonReader
, classOfT
);
742 assertFullConsumption(object
, jsonReader
);
743 return Primitives
.wrap(classOfT
).cast(object
);
747 * This method deserializes the Json read from the specified reader into an object of the
748 * specified type. This method is useful if the specified object is a generic type. For
749 * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the Json in a
750 * String form instead of a {@link Reader}, use {@link #fromJson(String, Type)} instead.
752 * @param <T> the type of the desired object
753 * @param json the reader producing Json from which the object is to be deserialized
754 * @param typeOfT The specific genericized type of src. You can obtain this type by using the
755 * {@link com.google.gson.reflect.TypeToken} class. For example, to get the type for
756 * {@code Collection<Foo>}, you should use:
758 * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
760 * @return an object of type T from the json
761 * @throws JsonIOException if there was a problem reading from the Reader
762 * @throws JsonSyntaxException if json is not a valid representation for an object of type
765 @SuppressWarnings("unchecked")
766 public <T
> T
fromJson(Reader json
, Type typeOfT
) throws JsonIOException
, JsonSyntaxException
{
767 JsonReader jsonReader
= new JsonReader(json
);
768 T object
= (T
) fromJson(jsonReader
, typeOfT
);
769 assertFullConsumption(object
, jsonReader
);
773 private static void assertFullConsumption(Object obj
, JsonReader reader
) {
775 if (obj
!= null && reader
.peek() != JsonToken
.END_DOCUMENT
) {
776 throw new JsonIOException("JSON document was not fully consumed.");
778 } catch (MalformedJsonException e
) {
779 throw new JsonSyntaxException(e
);
780 } catch (IOException e
) {
781 throw new JsonIOException(e
);
786 * Reads the next JSON value from {@code reader} and convert it to an object
787 * of type {@code typeOfT}.
788 * Since Type is not parameterized by T, this method is type unsafe and should be used carefully
790 * @throws JsonIOException if there was a problem writing to the Reader
791 * @throws JsonSyntaxException if json is not a valid representation for an object of type
793 @SuppressWarnings("unchecked")
794 public <T
> T
fromJson(JsonReader reader
, Type typeOfT
) throws JsonIOException
, JsonSyntaxException
{
795 boolean isEmpty
= true;
796 boolean oldLenient
= reader
.isLenient();
797 reader
.setLenient(true);
801 TypeToken
<T
> typeToken
= (TypeToken
<T
>) TypeToken
.get(typeOfT
);
802 TypeAdapter
<T
> typeAdapter
= getAdapter(typeToken
);
803 T object
= typeAdapter
.read(reader
);
805 } catch (EOFException e
) {
807 * For compatibility with JSON 1.5 and earlier, we return null for empty
808 * documents instead of throwing.
813 throw new JsonSyntaxException(e
);
814 } catch (IllegalStateException e
) {
815 throw new JsonSyntaxException(e
);
816 } catch (IOException e
) {
817 // TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException
818 throw new JsonSyntaxException(e
);
820 reader
.setLenient(oldLenient
);
825 * This method deserializes the Json read from the specified parse tree into an object of the
826 * specified type. It is not suitable to use if the specified class is a generic type since it
827 * will not have the generic type information because of the Type Erasure feature of Java.
828 * Therefore, this method should not be used if the desired type is a generic type. Note that
829 * this method works fine if the any of the fields of the specified object are generics, just the
830 * object itself should not be a generic type. For the cases when the object is of generic type,
831 * invoke {@link #fromJson(JsonElement, Type)}.
832 * @param <T> the type of the desired object
833 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to
835 * @param classOfT The class of T
836 * @return an object of type T from the json
837 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT
840 public <T
> T
fromJson(JsonElement json
, Class
<T
> classOfT
) throws JsonSyntaxException
{
841 Object object
= fromJson(json
, (Type
) classOfT
);
842 return Primitives
.wrap(classOfT
).cast(object
);
846 * This method deserializes the Json read from the specified parse tree into an object of the
847 * specified type. This method is useful if the specified object is a generic type. For
848 * non-generic objects, use {@link #fromJson(JsonElement, Class)} instead.
850 * @param <T> the type of the desired object
851 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to
853 * @param typeOfT The specific genericized type of src. You can obtain this type by using the
854 * {@link com.google.gson.reflect.TypeToken} class. For example, to get the type for
855 * {@code Collection<Foo>}, you should use:
857 * Type typeOfT = new TypeToken<Collection<Foo>>(){}.getType();
859 * @return an object of type T from the json
860 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT
863 @SuppressWarnings("unchecked")
864 public <T
> T
fromJson(JsonElement json
, Type typeOfT
) throws JsonSyntaxException
{
868 return (T
) fromJson(new JsonTreeReader(json
), typeOfT
);
871 static class FutureTypeAdapter
<T
> extends TypeAdapter
<T
> {
872 private TypeAdapter
<T
> delegate
;
874 public void setDelegate(TypeAdapter
<T
> typeAdapter
) {
875 if (delegate
!= null) {
876 throw new AssertionError();
878 delegate
= typeAdapter
;
881 @Override public T
read(JsonReader in
) throws IOException
{
882 if (delegate
== null) {
883 throw new IllegalStateException();
885 return delegate
.read(in
);
888 @Override public void write(JsonWriter out
, T value
) throws IOException
{
889 if (delegate
== null) {
890 throw new IllegalStateException();
892 delegate
.write(out
, value
);
897 public String
toString() {
898 return new StringBuilder("{serializeNulls:")
899 .append(serializeNulls
)
900 .append("factories:").append(factories
)
901 .append(",instanceCreators:").append(constructorConstructor
)