1616
1717package com .google .gson ;
1818
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-
3819import com .google .gson .internal .ConstructorConstructor ;
3920import com .google .gson .internal .Excluder ;
4021import com .google .gson .internal .GsonBuildConfig ;
5839import com .google .gson .stream .JsonToken ;
5940import com .google .gson .stream .JsonWriter ;
6041import 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 ;
6160
6261/**
6362 * This is the main class for using Gson. Gson is typically used by first constructing a
9796 * <p>See the <a href="https://sites.google.com/site/gson/gson-user-guide">Gson User Guide</a>
9897 * for a more complete set of examples.</p>
9998 *
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+ *
100126 * @see com.google.gson.reflect.TypeToken
101127 *
102128 * @author Inderjeet Singh
@@ -736,6 +762,15 @@ public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOE
736762 /**
737763 * Writes the JSON representation of {@code src} of type {@code typeOfSrc} to
738764 * {@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+ *
739774 * @throws JsonIOException if there was a problem writing to the writer
740775 */
741776 @ SuppressWarnings ("unchecked" )
@@ -834,6 +869,15 @@ public JsonReader newJsonReader(Reader reader) {
834869
835870 /**
836871 * 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+ *
837881 * @throws JsonIOException if there was a problem writing to the writer
838882 */
839883 public void toJson (JsonElement jsonElement , JsonWriter writer ) throws JsonIOException {
@@ -868,6 +912,9 @@ public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOExce
868912 * {@link #fromJson(String, Type)}. If you have the Json in a {@link Reader} instead of
869913 * a String, use {@link #fromJson(Reader, Class)} instead.
870914 *
915+ * <p>An exception is thrown if the JSON string has multiple top-level JSON elements,
916+ * or if there is trailing data.
917+ *
871918 * @param <T> the type of the desired object
872919 * @param json the string from which the object is to be deserialized
873920 * @param classOfT the class of T
@@ -887,6 +934,9 @@ public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException
887934 * {@link #fromJson(String, Class)} instead. If you have the Json in a {@link Reader} instead of
888935 * a String, use {@link #fromJson(Reader, Type)} instead.
889936 *
937+ * <p>An exception is thrown if the JSON string has multiple top-level JSON elements,
938+ * or if there is trailing data.
939+ *
890940 * @param <T> the type of the desired object
891941 * @param json the string from which the object is to be deserialized
892942 * @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 {
920970 * invoke {@link #fromJson(Reader, Type)}. If you have the Json in a String form instead of a
921971 * {@link Reader}, use {@link #fromJson(String, Class)} instead.
922972 *
973+ * <p>An exception is thrown if the JSON data has multiple top-level JSON elements,
974+ * or if there is trailing data.
975+ *
923976 * @param <T> the type of the desired object
924977 * @param json the reader producing the Json from which the object is to be deserialized.
925978 * @param classOfT the class of T
@@ -941,6 +994,9 @@ public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException
941994 * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the Json in a
942995 * String form instead of a {@link Reader}, use {@link #fromJson(String, Type)} instead.
943996 *
997+ * <p>An exception is thrown if the JSON data has multiple top-level JSON elements,
998+ * or if there is trailing data.
999+ *
9441000 * @param <T> the type of the desired object
9451001 * @param json the reader producing Json from which the object is to be deserialized
9461002 * @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
9651021 private static void assertFullConsumption (Object obj , JsonReader reader ) {
9661022 try {
9671023 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." );
9691025 }
9701026 } catch (MalformedJsonException e ) {
9711027 throw new JsonSyntaxException (e );
@@ -977,7 +1033,14 @@ private static void assertFullConsumption(Object obj, JsonReader reader) {
9771033 /**
9781034 * Reads the next JSON value from {@code reader} and convert it to an object
9791035 * 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.
9811044 *
9821045 * @throws JsonIOException if there was a problem writing to the Reader
9831046 * @throws JsonSyntaxException if json is not a valid representation for an object of type
0 commit comments