16
16
17
17
package com .google .gson ;
18
18
19
- import java .io .EOFException ;
20
- import java .io .IOException ;
21
- import java .io .Reader ;
22
- import java .io .StringReader ;
23
- import java .io .StringWriter ;
24
- import java .io .Writer ;
25
- import java .lang .reflect .Type ;
26
- import java .math .BigDecimal ;
27
- import java .math .BigInteger ;
28
- import java .text .DateFormat ;
29
- import java .util .ArrayList ;
30
- import java .util .Collections ;
31
- import java .util .HashMap ;
32
- import java .util .List ;
33
- import java .util .Map ;
34
- import java .util .concurrent .ConcurrentHashMap ;
35
- import java .util .concurrent .atomic .AtomicLong ;
36
- import java .util .concurrent .atomic .AtomicLongArray ;
37
-
38
19
import com .google .gson .internal .ConstructorConstructor ;
39
20
import com .google .gson .internal .Excluder ;
40
21
import com .google .gson .internal .GsonBuildConfig ;
58
39
import com .google .gson .stream .JsonToken ;
59
40
import com .google .gson .stream .JsonWriter ;
60
41
import com .google .gson .stream .MalformedJsonException ;
42
+ import java .io .EOFException ;
43
+ import java .io .IOException ;
44
+ import java .io .Reader ;
45
+ import java .io .StringReader ;
46
+ import java .io .StringWriter ;
47
+ import java .io .Writer ;
48
+ import java .lang .reflect .Type ;
49
+ import java .math .BigDecimal ;
50
+ import java .math .BigInteger ;
51
+ import java .text .DateFormat ;
52
+ import java .util .ArrayList ;
53
+ import java .util .Collections ;
54
+ import java .util .HashMap ;
55
+ import java .util .List ;
56
+ import java .util .Map ;
57
+ import java .util .concurrent .ConcurrentHashMap ;
58
+ import java .util .concurrent .atomic .AtomicLong ;
59
+ import java .util .concurrent .atomic .AtomicLongArray ;
61
60
62
61
/**
63
62
* This is the main class for using Gson. Gson is typically used by first constructing a
97
96
* <p>See the <a href="https://sites.google.com/site/gson/gson-user-guide">Gson User Guide</a>
98
97
* for a more complete set of examples.</p>
99
98
*
99
+ * <h2>Lenient JSON handling</h2>
100
+ * For legacy reasons most of the {@code Gson} methods allow JSON data which does not
101
+ * comply with the JSON specification, regardless of whether {@link GsonBuilder#setLenient()}
102
+ * is used or not. If this behavior is not desired, the following workarounds can be used:
103
+ *
104
+ * <h3>Serialization</h3>
105
+ * <ol>
106
+ * <li>Use {@link #getAdapter(Class)} to obtain the adapter for the type to be serialized
107
+ * <li>When using an existing {@code JsonWriter}, manually apply the writer settings of this
108
+ * {@code Gson} instance listed by {@link #newJsonWriter(Writer)}.<br>
109
+ * Otherwise, when not using an existing {@code JsonWriter}, use {@link #newJsonWriter(Writer)}
110
+ * to construct one.
111
+ * <li>Call {@link TypeAdapter#write(JsonWriter, Object)}
112
+ * </ol>
113
+ *
114
+ * <h3>Deserialization</h3>
115
+ * <ol>
116
+ * <li>Use {@link #getAdapter(Class)} to obtain the adapter for the type to be deserialized
117
+ * <li>When using an existing {@code JsonReader}, manually apply the reader settings of this
118
+ * {@code Gson} instance listed by {@link #newJsonReader(Reader)}.<br>
119
+ * Otherwise, when not using an existing {@code JsonReader}, use {@link #newJsonReader(Reader)}
120
+ * to construct one.
121
+ * <li>Call {@link TypeAdapter#read(JsonReader)}
122
+ * <li>Call {@link JsonReader#peek()} and verify that the result is {@link JsonToken#END_DOCUMENT}
123
+ * to make sure there is no trailing data
124
+ * </ol>
125
+ *
100
126
* @see com.google.gson.reflect.TypeToken
101
127
*
102
128
* @author Inderjeet Singh
@@ -736,6 +762,15 @@ public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOE
736
762
/**
737
763
* Writes the JSON representation of {@code src} of type {@code typeOfSrc} to
738
764
* {@code writer}.
765
+ *
766
+ * <p>The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode},
767
+ * regardless of the lenient mode setting of the provided writer. The lenient mode setting
768
+ * of the writer is restored once this method returns.
769
+ *
770
+ * <p>The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance
771
+ * (configured by the {@link GsonBuilder}) are applied, and the original settings of the
772
+ * writer are restored once this method returns.
773
+ *
739
774
* @throws JsonIOException if there was a problem writing to the writer
740
775
*/
741
776
@ SuppressWarnings ("unchecked" )
@@ -834,6 +869,15 @@ public JsonReader newJsonReader(Reader reader) {
834
869
835
870
/**
836
871
* Writes the JSON for {@code jsonElement} to {@code writer}.
872
+ *
873
+ * <p>The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode},
874
+ * regardless of the lenient mode setting of the provided writer. The lenient mode setting
875
+ * of the writer is restored once this method returns.
876
+ *
877
+ * <p>The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance
878
+ * (configured by the {@link GsonBuilder}) are applied, and the original settings of the
879
+ * writer are restored once this method returns.
880
+ *
837
881
* @throws JsonIOException if there was a problem writing to the writer
838
882
*/
839
883
public void toJson (JsonElement jsonElement , JsonWriter writer ) throws JsonIOException {
@@ -868,6 +912,9 @@ public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOExce
868
912
* {@link #fromJson(String, Type)}. If you have the Json in a {@link Reader} instead of
869
913
* a String, use {@link #fromJson(Reader, Class)} instead.
870
914
*
915
+ * <p>An exception is thrown if the JSON string has multiple top-level JSON elements,
916
+ * or if there is trailing data.
917
+ *
871
918
* @param <T> the type of the desired object
872
919
* @param json the string from which the object is to be deserialized
873
920
* @param classOfT the class of T
@@ -887,6 +934,9 @@ public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException
887
934
* {@link #fromJson(String, Class)} instead. If you have the Json in a {@link Reader} instead of
888
935
* a String, use {@link #fromJson(Reader, Type)} instead.
889
936
*
937
+ * <p>An exception is thrown if the JSON string has multiple top-level JSON elements,
938
+ * or if there is trailing data.
939
+ *
890
940
* @param <T> the type of the desired object
891
941
* @param json the string from which the object is to be deserialized
892
942
* @param typeOfT The specific genericized type of src. You can obtain this type by using the
@@ -920,6 +970,9 @@ public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException {
920
970
* invoke {@link #fromJson(Reader, Type)}. If you have the Json in a String form instead of a
921
971
* {@link Reader}, use {@link #fromJson(String, Class)} instead.
922
972
*
973
+ * <p>An exception is thrown if the JSON data has multiple top-level JSON elements,
974
+ * or if there is trailing data.
975
+ *
923
976
* @param <T> the type of the desired object
924
977
* @param json the reader producing the Json from which the object is to be deserialized.
925
978
* @param classOfT the class of T
@@ -941,6 +994,9 @@ public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException
941
994
* non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the Json in a
942
995
* String form instead of a {@link Reader}, use {@link #fromJson(String, Type)} instead.
943
996
*
997
+ * <p>An exception is thrown if the JSON data has multiple top-level JSON elements,
998
+ * or if there is trailing data.
999
+ *
944
1000
* @param <T> the type of the desired object
945
1001
* @param json the reader producing Json from which the object is to be deserialized
946
1002
* @param typeOfT The specific genericized type of src. You can obtain this type by using the
@@ -965,7 +1021,7 @@ public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyn
965
1021
private static void assertFullConsumption (Object obj , JsonReader reader ) {
966
1022
try {
967
1023
if (obj != null && reader .peek () != JsonToken .END_DOCUMENT ) {
968
- throw new JsonIOException ("JSON document was not fully consumed." );
1024
+ throw new JsonSyntaxException ("JSON document was not fully consumed." );
969
1025
}
970
1026
} catch (MalformedJsonException e ) {
971
1027
throw new JsonSyntaxException (e );
@@ -977,7 +1033,14 @@ private static void assertFullConsumption(Object obj, JsonReader reader) {
977
1033
/**
978
1034
* Reads the next JSON value from {@code reader} and convert it to an object
979
1035
* of type {@code typeOfT}. Returns {@code null}, if the {@code reader} is at EOF.
980
- * Since Type is not parameterized by T, this method is type unsafe and should be used carefully
1036
+ * Since Type is not parameterized by T, this method is type unsafe and should be used carefully.
1037
+ *
1038
+ * <p>Unlike the other {@code fromJson} methods, no exception is thrown if the JSON data has
1039
+ * multiple top-level JSON elements, or if there is trailing data.
1040
+ *
1041
+ * <p>The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode},
1042
+ * regardless of the lenient mode setting of the provided reader. The lenient mode setting
1043
+ * of the reader is restored once this method returns.
981
1044
*
982
1045
* @throws JsonIOException if there was a problem writing to the Reader
983
1046
* @throws JsonSyntaxException if json is not a valid representation for an object of type
0 commit comments