builderFactories,
@@ -265,7 +276,7 @@ public Gson() {
this.generateNonExecutableJson = generateNonExecutableGson;
this.htmlSafe = htmlSafe;
this.formattingStyle = formattingStyle;
- this.lenient = lenient;
+ this.strictness = strictness;
this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues;
this.useJdkUnsafe = useJdkUnsafe;
this.longSerializationPolicy = longSerializationPolicy;
@@ -802,7 +813,7 @@ public void toJson(Object src, Appendable writer) throws JsonIOException {
*
* Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType();
*
- * @param writer Writer to which the JSON representation of src needs to be written.
+ * @param writer Writer to which the JSON representation of src needs to be written
* @throws JsonIOException if there was a problem writing to the writer
* @since 1.2
*
@@ -822,24 +833,38 @@ public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOE
* Writes the JSON representation of {@code src} of type {@code typeOfSrc} to
* {@code writer}.
*
- * The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode},
- * regardless of the lenient mode setting of the provided writer. The lenient mode setting
- * of the writer is restored once this method returns.
+ *
If the {@code Gson} instance has an {@linkplain GsonBuilder#setStrictness(Strictness) explicit strictness setting},
+ * this setting will be used for writing the JSON regardless of the {@linkplain JsonWriter#getStrictness() strictness}
+ * of the provided {@link JsonWriter}. For legacy reasons, if the {@code Gson} instance has no explicit strictness setting
+ * and the writer does not have the strictness {@link Strictness#STRICT}, the JSON will be written in {@link Strictness#LENIENT}
+ * mode.
+ * Note that in all cases the old strictness setting of the writer will be restored when this method returns.
*
*
The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance
* (configured by the {@link GsonBuilder}) are applied, and the original settings of the
* writer are restored once this method returns.
*
+ * @param src the object for which JSON representation is to be created
+ * @param typeOfSrc the type of the object to be written
+ * @param writer Writer to which the JSON representation of src needs to be written
+ *
* @throws JsonIOException if there was a problem writing to the writer
*/
public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {
@SuppressWarnings("unchecked")
TypeAdapter adapter = (TypeAdapter) getAdapter(TypeToken.get(typeOfSrc));
- boolean oldLenient = writer.isLenient();
- writer.setLenient(true);
+
+ Strictness oldStrictness = writer.getStrictness();
+ if (this.strictness != null) {
+ writer.setStrictness(this.strictness);
+ } else if (writer.getStrictness() != Strictness.STRICT) {
+ writer.setStrictness(Strictness.LENIENT);
+ }
+
boolean oldHtmlSafe = writer.isHtmlSafe();
- writer.setHtmlSafe(htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
+
+ writer.setHtmlSafe(htmlSafe);
writer.setSerializeNulls(serializeNulls);
try {
adapter.write(writer, src);
@@ -848,7 +873,7 @@ public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOE
} catch (AssertionError e) {
throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e);
} finally {
- writer.setLenient(oldLenient);
+ writer.setStrictness(oldStrictness);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
@@ -892,7 +917,10 @@ public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOExce
* {@link GsonBuilder#disableHtmlEscaping()}
* {@link GsonBuilder#generateNonExecutableJson()}
* {@link GsonBuilder#serializeNulls()}
- * {@link GsonBuilder#setLenient()}
+ * {@link GsonBuilder#setStrictness(Strictness)}. If no
+ * {@linkplain GsonBuilder#setStrictness(Strictness) explicit strictness has been set} the created
+ * writer will have a strictness of {@link Strictness#LEGACY_STRICT}. Otherwise, the strictness of
+ * the {@code Gson} instance will be used for the created writer.
* {@link GsonBuilder#setPrettyPrinting()}
* {@link GsonBuilder#setFormattingStyle(FormattingStyle)}
*
@@ -904,7 +932,7 @@ public JsonWriter newJsonWriter(Writer writer) throws IOException {
JsonWriter jsonWriter = new JsonWriter(writer);
jsonWriter.setFormattingStyle(formattingStyle);
jsonWriter.setHtmlSafe(htmlSafe);
- jsonWriter.setLenient(lenient);
+ jsonWriter.setStrictness(strictness == null ? Strictness.LEGACY_STRICT : strictness);
jsonWriter.setSerializeNulls(serializeNulls);
return jsonWriter;
}
@@ -914,35 +942,50 @@ public JsonWriter newJsonWriter(Writer writer) throws IOException {
*
* The following settings are considered:
*
- * {@link GsonBuilder#setLenient()}
+ * {@link GsonBuilder#setStrictness(Strictness)}. If no
+ * {@linkplain GsonBuilder#setStrictness(Strictness) explicit strictness has been set} the created
+ * reader will have a strictness of {@link Strictness#LEGACY_STRICT}. Otherwise, the strictness of
+ * the {@code Gson} instance will be used for the created reader.
*
*/
public JsonReader newJsonReader(Reader reader) {
JsonReader jsonReader = new JsonReader(reader);
- jsonReader.setLenient(lenient);
+ jsonReader.setStrictness(strictness == null ? Strictness.LEGACY_STRICT : strictness);
return jsonReader;
}
/**
* Writes the JSON for {@code jsonElement} to {@code writer}.
*
- * The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode},
- * regardless of the lenient mode setting of the provided writer. The lenient mode setting
- * of the writer is restored once this method returns.
+ *
If the {@code Gson} instance has an {@linkplain GsonBuilder#setStrictness(Strictness) explicit strictness setting},
+ * this setting will be used for writing the JSON regardless of the {@linkplain JsonWriter#getStrictness() strictness}
+ * of the provided {@link JsonWriter}. For legacy reasons, if the {@code Gson} instance has no explicit strictness setting
+ * and the writer does not have the strictness {@link Strictness#STRICT}, the JSON will be written in {@link Strictness#LENIENT}
+ * mode.
+ * Note that in all cases the old strictness setting of the writer will be restored when this method returns.
*
*
The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance
* (configured by the {@link GsonBuilder}) are applied, and the original settings of the
* writer are restored once this method returns.
*
+ * @param jsonElement the JSON element to be written
+ * @param writer the JSON writer to which the provided element will be written
* @throws JsonIOException if there was a problem writing to the writer
*/
public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException {
- boolean oldLenient = writer.isLenient();
- writer.setLenient(true);
+ Strictness oldStrictness = writer.getStrictness();
boolean oldHtmlSafe = writer.isHtmlSafe();
- writer.setHtmlSafe(htmlSafe);
boolean oldSerializeNulls = writer.getSerializeNulls();
+
+ writer.setHtmlSafe(htmlSafe);
writer.setSerializeNulls(serializeNulls);
+
+ if (this.strictness != null) {
+ writer.setStrictness(this.strictness);
+ } else if (writer.getStrictness() != Strictness.STRICT) {
+ writer.setStrictness(Strictness.LENIENT);
+ }
+
try {
Streams.write(jsonElement, writer);
} catch (IOException e) {
@@ -950,7 +993,7 @@ public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOExce
} catch (AssertionError e) {
throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e);
} finally {
- writer.setLenient(oldLenient);
+ writer.setStrictness(oldStrictness);
writer.setHtmlSafe(oldHtmlSafe);
writer.setSerializeNulls(oldSerializeNulls);
}
@@ -1169,9 +1212,12 @@ private static void assertFullConsumption(Object obj, JsonReader reader) {
*
Unlike the other {@code fromJson} methods, no exception is thrown if the JSON data has
* multiple top-level JSON elements, or if there is trailing data.
*
- *
The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode},
- * regardless of the lenient mode setting of the provided reader. The lenient mode setting
- * of the reader is restored once this method returns.
+ *
If the {@code Gson} instance has an {@linkplain GsonBuilder#setStrictness(Strictness) explicit strictness setting},
+ * this setting will be used for reading the JSON regardless of the {@linkplain JsonReader#getStrictness() strictness}
+ * of the provided {@link JsonReader}. For legacy reasons, if the {@code Gson} instance has no explicit strictness setting
+ * and the reader does not have the strictness {@link Strictness#STRICT}, the JSON will be written in {@link Strictness#LENIENT}
+ * mode.
+ * Note that in all cases the old strictness setting of the reader will be restored when this method returns.
*
* @param the type of the desired object
* @param reader the reader whose next JSON value should be deserialized
@@ -1198,9 +1244,12 @@ public T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, J
* Unlike the other {@code fromJson} methods, no exception is thrown if the JSON data has
* multiple top-level JSON elements, or if there is trailing data.
*
- *
The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode},
- * regardless of the lenient mode setting of the provided reader. The lenient mode setting
- * of the reader is restored once this method returns.
+ *
If the {@code Gson} instance has an {@linkplain GsonBuilder#setStrictness(Strictness) explicit strictness setting},
+ * this setting will be used for reading the JSON regardless of the {@linkplain JsonReader#getStrictness() strictness}
+ * of the provided {@link JsonReader}. For legacy reasons, if the {@code Gson} instance has no explicit strictness setting
+ * and the reader does not have the strictness {@link Strictness#STRICT}, the JSON will be written in {@link Strictness#LENIENT}
+ * mode.
+ * Note that in all cases the old strictness setting of the reader will be restored when this method returns.
*
* @param the type of the desired object
* @param reader the reader whose next JSON value should be deserialized
@@ -1220,8 +1269,14 @@ public T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, J
*/
public T fromJson(JsonReader reader, TypeToken typeOfT) throws JsonIOException, JsonSyntaxException {
boolean isEmpty = true;
- boolean oldLenient = reader.isLenient();
- reader.setLenient(true);
+ Strictness oldStrictness = reader.getStrictness();
+
+ if (this.strictness != null) {
+ reader.setStrictness(this.strictness);
+ } else if (reader.getStrictness() != Strictness.STRICT) {
+ reader.setStrictness(Strictness.LENIENT);
+ }
+
try {
JsonToken unused = reader.peek();
isEmpty = false;
@@ -1244,7 +1299,7 @@ public T fromJson(JsonReader reader, TypeToken typeOfT) throws JsonIOExce
} catch (AssertionError e) {
throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e);
} finally {
- reader.setLenient(oldLenient);
+ reader.setStrictness(oldStrictness);
}
}
diff --git a/gson/src/main/java/com/google/gson/GsonBuilder.java b/gson/src/main/java/com/google/gson/GsonBuilder.java
index c72c411f07..68eb7d718b 100644
--- a/gson/src/main/java/com/google/gson/GsonBuilder.java
+++ b/gson/src/main/java/com/google/gson/GsonBuilder.java
@@ -21,14 +21,15 @@
import static com.google.gson.Gson.DEFAULT_ESCAPE_HTML;
import static com.google.gson.Gson.DEFAULT_FORMATTING_STYLE;
import static com.google.gson.Gson.DEFAULT_JSON_NON_EXECUTABLE;
-import static com.google.gson.Gson.DEFAULT_LENIENT;
import static com.google.gson.Gson.DEFAULT_NUMBER_TO_NUMBER_STRATEGY;
import static com.google.gson.Gson.DEFAULT_OBJECT_TO_NUMBER_STRATEGY;
import static com.google.gson.Gson.DEFAULT_SERIALIZE_NULLS;
import static com.google.gson.Gson.DEFAULT_SPECIALIZE_FLOAT_VALUES;
+import static com.google.gson.Gson.DEFAULT_STRICTNESS;
import static com.google.gson.Gson.DEFAULT_USE_JDK_UNSAFE;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.errorprone.annotations.InlineMe;
import com.google.gson.annotations.Since;
import com.google.gson.annotations.Until;
import com.google.gson.internal.$Gson$Preconditions;
@@ -71,12 +72,16 @@
* .create();
*
*
- * NOTES:
+ *
Notes:
*
- * the order of invocation of configuration methods does not matter.
- * The default serialization of {@link Date} and its subclasses in Gson does
+ * The order of invocation of configuration methods does not matter.
+ * The default serialization of {@link Date} and its subclasses in Gson does
* not contain time-zone information. So, if you are using date/time instances,
* use {@code GsonBuilder} and its {@code setDateFormat} methods.
+ * By default no explicit {@link Strictness} is set; some of the {@link Gson} methods
+ * behave as if {@link Strictness#LEGACY_STRICT} was used whereas others behave as
+ * if {@link Strictness#LENIENT} was used. Prefer explicitly setting a strictness
+ * with {@link #setStrictness(Strictness)} to avoid this legacy behavior.
*
*
* @author Inderjeet Singh
@@ -100,7 +105,7 @@ public final class GsonBuilder {
private boolean escapeHtmlChars = DEFAULT_ESCAPE_HTML;
private FormattingStyle formattingStyle = DEFAULT_FORMATTING_STYLE;
private boolean generateNonExecutableJson = DEFAULT_JSON_NON_EXECUTABLE;
- private boolean lenient = DEFAULT_LENIENT;
+ private Strictness strictness = DEFAULT_STRICTNESS;
private boolean useJdkUnsafe = DEFAULT_USE_JDK_UNSAFE;
private ToNumberStrategy objectToNumberStrategy = DEFAULT_OBJECT_TO_NUMBER_STRATEGY;
private ToNumberStrategy numberToNumberStrategy = DEFAULT_NUMBER_TO_NUMBER_STRATEGY;
@@ -130,7 +135,7 @@ public GsonBuilder() {
this.generateNonExecutableJson = gson.generateNonExecutableJson;
this.escapeHtmlChars = gson.htmlSafe;
this.formattingStyle = gson.formattingStyle;
- this.lenient = gson.lenient;
+ this.strictness = gson.strictness;
this.serializeSpecialFloatingPointValues = gson.serializeSpecialFloatingPointValues;
this.longSerializationPolicy = gson.longSerializationPolicy;
this.datePattern = gson.datePattern;
@@ -521,18 +526,40 @@ public GsonBuilder setFormattingStyle(FormattingStyle formattingStyle) {
}
/**
- * Configures Gson to allow JSON data which does not strictly comply with the JSON specification.
+ * Sets the strictness of this builder to {@link Strictness#LENIENT}.
*
- * Note: Due to legacy reasons most methods of Gson are always lenient, regardless of
- * whether this builder method is used.
+ * @deprecated This method is equivalent to calling {@link #setStrictness(Strictness)} with
+ * {@link Strictness#LENIENT}: {@code setStrictness(Strictness.LENIENT)}
*
- * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
- * @see JsonReader#setLenient(boolean)
- * @see JsonWriter#setLenient(boolean)
+ * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern.
+ * @see JsonReader#setStrictness(Strictness)
+ * @see JsonWriter#setStrictness(Strictness)
+ * @see #setStrictness(Strictness)
*/
+ @Deprecated
+ @InlineMe(replacement = "this.setStrictness(Strictness.LENIENT)", imports = "com.google.gson.Strictness")
@CanIgnoreReturnValue
public GsonBuilder setLenient() {
- lenient = true;
+ return setStrictness(Strictness.LENIENT);
+ }
+
+ /**
+ * Sets the strictness of this builder to the provided parameter.
+ *
+ *
This changes how strict the
+ * RFC 8259 JSON specification is enforced when parsing or
+ * writing JSON. For details on this, refer to {@link JsonReader#setStrictness(Strictness)} and
+ * {@link JsonWriter#setStrictness(Strictness)}.
+ *
+ * @param strictness the new strictness mode. May not be {@code null}.
+ * @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern.
+ * @see JsonReader#setStrictness(Strictness)
+ * @see JsonWriter#setStrictness(Strictness)
+ * @since $next-version$
+ */
+ @CanIgnoreReturnValue
+ public GsonBuilder setStrictness(Strictness strictness) {
+ this.strictness = Objects.requireNonNull(strictness);
return this;
}
@@ -711,7 +738,7 @@ public GsonBuilder registerTypeHierarchyAdapter(Class> baseType, Object typeAd
}
/**
- * Section 2.4 of JSON specification disallows
+ * Section 6 of JSON specification disallows
* special double values (NaN, Infinity, -Infinity). However,
* Javascript
* specification (see section 4.3.20, 4.3.22, 4.3.23) allows these values as valid Javascript
@@ -804,7 +831,7 @@ public Gson create() {
return new Gson(excluder, fieldNamingPolicy, new HashMap<>(instanceCreators),
serializeNulls, complexMapKeySerialization,
- generateNonExecutableJson, escapeHtmlChars, formattingStyle, lenient,
+ generateNonExecutableJson, escapeHtmlChars, formattingStyle, strictness,
serializeSpecialFloatingPointValues, useJdkUnsafe, longSerializationPolicy,
datePattern, dateStyle, timeStyle, new ArrayList<>(this.factories),
new ArrayList<>(this.hierarchyFactories), factories,
diff --git a/gson/src/main/java/com/google/gson/JsonElement.java b/gson/src/main/java/com/google/gson/JsonElement.java
index 23e5654aac..1b440d0532 100644
--- a/gson/src/main/java/com/google/gson/JsonElement.java
+++ b/gson/src/main/java/com/google/gson/JsonElement.java
@@ -321,7 +321,8 @@ public String toString() {
try {
StringWriter stringWriter = new StringWriter();
JsonWriter jsonWriter = new JsonWriter(stringWriter);
- jsonWriter.setLenient(true);
+ // Make writer lenient because toString() must not fail, even if for example JsonPrimitive contains NaN
+ jsonWriter.setStrictness(Strictness.LENIENT);
Streams.write(this, jsonWriter);
return stringWriter.toString();
} catch (IOException e) {
diff --git a/gson/src/main/java/com/google/gson/JsonParser.java b/gson/src/main/java/com/google/gson/JsonParser.java
index 20d3750cea..557d00c8e0 100644
--- a/gson/src/main/java/com/google/gson/JsonParser.java
+++ b/gson/src/main/java/com/google/gson/JsonParser.java
@@ -41,7 +41,7 @@ public JsonParser() {}
* An exception is thrown if the JSON string has multiple top-level JSON elements,
* or if there is trailing data.
*
- * The JSON string is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode}.
+ *
The JSON string is parsed in {@linkplain JsonReader#setStrictness(Strictness) lenient mode}.
*
* @param json JSON text
* @return a parse tree of {@link JsonElement}s corresponding to the specified JSON
@@ -57,7 +57,7 @@ public static JsonElement parseString(String json) throws JsonSyntaxException {
* An exception is thrown if the JSON string has multiple top-level JSON elements,
* or if there is trailing data.
*
- *
The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode}.
+ *
The JSON data is parsed in {@linkplain JsonReader#setStrictness(Strictness) lenient mode}.
*
* @param reader JSON text
* @return a parse tree of {@link JsonElement}s corresponding to the specified JSON
@@ -87,8 +87,8 @@ public static JsonElement parseReader(Reader reader) throws JsonIOException, Jso
* Unlike the other {@code parse} methods, no exception is thrown if the JSON data has
* multiple top-level JSON elements, or if there is trailing data.
*
- *
The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode},
- * regardless of the lenient mode setting of the provided reader. The lenient mode setting
+ *
The JSON data is parsed in {@linkplain JsonReader#setStrictness(Strictness) lenient mode},
+ * regardless of the strictness setting of the provided reader. The strictness setting
* of the reader is restored once this method returns.
*
* @throws JsonParseException if there is an IOException or if the specified
@@ -97,8 +97,8 @@ public static JsonElement parseReader(Reader reader) throws JsonIOException, Jso
*/
public static JsonElement parseReader(JsonReader reader)
throws JsonIOException, JsonSyntaxException {
- boolean lenient = reader.isLenient();
- reader.setLenient(true);
+ Strictness strictness = reader.getStrictness();
+ reader.setStrictness(Strictness.LENIENT);
try {
return Streams.parse(reader);
} catch (StackOverflowError e) {
@@ -106,7 +106,7 @@ public static JsonElement parseReader(JsonReader reader)
} catch (OutOfMemoryError e) {
throw new JsonParseException("Failed parsing JSON source: " + reader + " to Json", e);
} finally {
- reader.setLenient(lenient);
+ reader.setStrictness(strictness);
}
}
diff --git a/gson/src/main/java/com/google/gson/JsonStreamParser.java b/gson/src/main/java/com/google/gson/JsonStreamParser.java
index cbc2883ca8..7d2629368b 100644
--- a/gson/src/main/java/com/google/gson/JsonStreamParser.java
+++ b/gson/src/main/java/com/google/gson/JsonStreamParser.java
@@ -28,7 +28,7 @@
/**
* A streaming parser that allows reading of multiple {@link JsonElement}s from the specified reader
* asynchronously. The JSON data is parsed in lenient mode, see also
- * {@link JsonReader#setLenient(boolean)}.
+ * {@link JsonReader#setStrictness(Strictness)}.
*
*
This class is conditionally thread-safe (see Item 70, Effective Java second edition). To
* properly use this class across multiple threads, you will need to add some external
@@ -66,7 +66,7 @@ public JsonStreamParser(String json) {
*/
public JsonStreamParser(Reader reader) {
parser = new JsonReader(reader);
- parser.setLenient(true);
+ parser.setStrictness(Strictness.LENIENT);
lock = new Object();
}
diff --git a/gson/src/main/java/com/google/gson/Strictness.java b/gson/src/main/java/com/google/gson/Strictness.java
new file mode 100644
index 0000000000..f3bd3fe08f
--- /dev/null
+++ b/gson/src/main/java/com/google/gson/Strictness.java
@@ -0,0 +1,29 @@
+package com.google.gson;
+
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+
+/**
+ * Modes that indicate how strictly a JSON {@linkplain JsonReader reader} or
+ * {@linkplain JsonWriter writer} follows the syntax laid out in the
+ * RFC 8259 JSON specification .
+ *
+ *
You can look at {@link JsonReader#setStrictness(Strictness)} to see how the strictness
+ * affects the {@link JsonReader} and you can look at
+ * {@link JsonWriter#setStrictness(Strictness)} to see how the strictness
+ * affects the {@link JsonWriter}.
+ *
+ * @see JsonReader#setStrictness(Strictness)
+ * @see JsonWriter#setStrictness(Strictness)
+ * @since $next-version$
+ */
+public enum Strictness {
+ /** Allow large deviations from the JSON specification. */
+ LENIENT,
+
+ /** Allow certain small deviations from the JSON specification for legacy reasons. */
+ LEGACY_STRICT,
+
+ /** Strict compliance with the JSON specification. */
+ STRICT
+}
diff --git a/gson/src/main/java/com/google/gson/TypeAdapter.java b/gson/src/main/java/com/google/gson/TypeAdapter.java
index 5fdea225a5..405fb12ac2 100644
--- a/gson/src/main/java/com/google/gson/TypeAdapter.java
+++ b/gson/src/main/java/com/google/gson/TypeAdapter.java
@@ -34,8 +34,7 @@
* By default Gson converts application classes to JSON using its built-in type
* adapters. If Gson's default JSON conversion isn't appropriate for a type,
* extend this class to customize the conversion. Here's an example of a type
- * adapter for an (X,Y) coordinate point: {@code
- *
+ * adapter for an (X,Y) coordinate point: {@code
* public class PointAdapter extends TypeAdapter {
* public Point read(JsonReader reader) throws IOException {
* if (reader.peek() == JsonToken.NULL) {
@@ -85,8 +84,7 @@
* guarantees of {@link Gson} might not apply.
*
* To use a custom type adapter with Gson, you must register it with a
- * {@link GsonBuilder}:
{@code
- *
+ * {@link GsonBuilder}: {@code
* GsonBuilder builder = new GsonBuilder();
* builder.registerTypeAdapter(Point.class, new PointAdapter());
* // if PointAdapter didn't check for nulls in its read/write methods, you should instead use
@@ -102,14 +100,12 @@
// JSON Conversion
// A type adapter registered with Gson is automatically invoked while serializing
// or deserializing JSON. However, you can also use type adapters directly to serialize
-// and deserialize JSON. Here is an example for deserialization:
{@code
-//
+// and deserialize JSON. Here is an example for deserialization: {@code
// String json = "{'origin':'0,0','points':['1,2','3,4']}";
// TypeAdapter graphAdapter = gson.getAdapter(Graph.class);
// Graph graph = graphAdapter.fromJson(json);
// }
-// And an example for serialization: {@code
-//
+// And an example for serialization: {@code
// Graph graph = new Graph(...);
// TypeAdapter graphAdapter = gson.getAdapter(Graph.class);
// String json = graphAdapter.toJson(graph);
@@ -134,12 +130,12 @@ public TypeAdapter() {
/**
* Converts {@code value} to a JSON document and writes it to {@code out}.
- * Unlike Gson's similar {@link Gson#toJson(JsonElement, Appendable) toJson}
- * method, this write is strict. Create a {@link
- * JsonWriter#setLenient(boolean) lenient} {@code JsonWriter} and call
- * {@link #write(JsonWriter, Object)} for lenient writing.
*
- * @param value the Java object to convert. May be null.
+ * A {@link JsonWriter} with default configuration is used for writing the
+ * JSON data. To customize this behavior, create a {@link JsonWriter}, configure
+ * it and then use {@link #write(JsonWriter, Object)} instead.
+ *
+ * @param value the Java object to convert. May be {@code null}.
* @since 2.2
*/
public final void toJson(Writer out, T value) throws IOException {
@@ -151,8 +147,7 @@ public final void toJson(Writer out, T value) throws IOException {
* This wrapper method is used to make a type adapter null tolerant. In general, a
* type adapter is required to handle nulls in write and read methods. Here is how this
* is typically done:
- *
{@code
- *
+ * {@code
* Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class,
* new TypeAdapter() {
* public Foo read(JsonReader in) throws IOException {
@@ -173,8 +168,7 @@ public final void toJson(Writer out, T value) throws IOException {
* }
* You can avoid this boilerplate handling of nulls by wrapping your type adapter with
* this method. Here is how we will rewrite the above example:
- * {@code
- *
+ * {@code
* Gson gson = new GsonBuilder().registerTypeAdapter(Foo.class,
* new TypeAdapter() {
* public Foo read(JsonReader in) throws IOException {
@@ -207,13 +201,14 @@ public final TypeAdapter nullSafe() {
}
/**
- * Converts {@code value} to a JSON document. Unlike Gson's similar {@link
- * Gson#toJson(Object) toJson} method, this write is strict. Create a {@link
- * JsonWriter#setLenient(boolean) lenient} {@code JsonWriter} and call
- * {@link #write(JsonWriter, Object)} for lenient writing.
+ * Converts {@code value} to a JSON document.
+ *
+ * A {@link JsonWriter} with default configuration is used for writing the
+ * JSON data. To customize this behavior, create a {@link JsonWriter}, configure
+ * it and then use {@link #write(JsonWriter, Object)} instead.
*
* @throws JsonIOException wrapping {@code IOException}s thrown by {@link #write(JsonWriter, Object)}
- * @param value the Java object to convert. May be null.
+ * @param value the Java object to convert. May be {@code null}.
* @since 2.2
*/
public final String toJson(T value) {
@@ -229,7 +224,7 @@ public final String toJson(T value) {
/**
* Converts {@code value} to a JSON tree.
*
- * @param value the Java object to convert. May be null.
+ * @param value the Java object to convert. May be {@code null}.
* @return the converted JSON tree. May be {@link JsonNull}.
* @throws JsonIOException wrapping {@code IOException}s thrown by {@link #write(JsonWriter, Object)}
* @since 2.2
@@ -248,20 +243,22 @@ public final JsonElement toJsonTree(T value) {
* Reads one JSON value (an array, object, string, number, boolean or null)
* and converts it to a Java object. Returns the converted object.
*
- * @return the converted Java object. May be null.
+ * @return the converted Java object. May be {@code null}.
*/
public abstract T read(JsonReader in) throws IOException;
/**
- * Converts the JSON document in {@code in} to a Java object. Unlike Gson's
- * similar {@link Gson#fromJson(Reader, Class) fromJson} method, this
- * read is strict. Create a {@link JsonReader#setLenient(boolean) lenient}
- * {@code JsonReader} and call {@link #read(JsonReader)} for lenient reading.
+ * Converts the JSON document in {@code in} to a Java object.
+ *
+ *
A {@link JsonReader} with default configuration (that is with
+ * {@link Strictness#LEGACY_STRICT} as strictness) is used for reading the JSON data.
+ * To customize this behavior, create a {@link JsonReader}, configure it and then
+ * use {@link #read(JsonReader)} instead.
*
*
No exception is thrown if the JSON data has multiple top-level JSON elements,
* or if there is trailing data.
*
- * @return the converted Java object. May be null.
+ * @return the converted Java object. May be {@code null}.
* @since 2.2
*/
public final T fromJson(Reader in) throws IOException {
@@ -270,15 +267,17 @@ public final T fromJson(Reader in) throws IOException {
}
/**
- * Converts the JSON document in {@code json} to a Java object. Unlike Gson's
- * similar {@link Gson#fromJson(String, Class) fromJson} method, this read is
- * strict. Create a {@link JsonReader#setLenient(boolean) lenient} {@code
- * JsonReader} and call {@link #read(JsonReader)} for lenient reading.
+ * Converts the JSON document in {@code json} to a Java object.
+ *
+ *
A {@link JsonReader} with default configuration (that is with
+ * {@link Strictness#LEGACY_STRICT} as strictness) is used for reading the JSON data.
+ * To customize this behavior, create a {@link JsonReader}, configure it and then
+ * use {@link #read(JsonReader)} instead.
*
*
No exception is thrown if the JSON data has multiple top-level JSON elements,
* or if there is trailing data.
*
- * @return the converted Java object. May be null.
+ * @return the converted Java object. May be {@code null}.
* @since 2.2
*/
public final T fromJson(String json) throws IOException {
@@ -289,7 +288,7 @@ public final T fromJson(String json) throws IOException {
* Converts {@code jsonTree} to a Java object.
*
* @param jsonTree the JSON element to convert. May be {@link JsonNull}.
- * @return the converted Java object. May be null.
+ * @return the converted Java object. May be {@code null}.
* @throws JsonIOException wrapping {@code IOException}s thrown by {@link #read(JsonReader)}
* @since 2.2
*/
diff --git a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
index 0f414e81e9..152f0482af 100644
--- a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
+++ b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
@@ -570,7 +570,11 @@ public InetAddress read(JsonReader in) throws IOException {
return null;
}
// regrettably, this should have included both the host name and the host address
- return InetAddress.getByName(in.nextString());
+ // For compatibility, we use InetAddress.getByName rather than the possibly-better
+ // .getAllByName
+ @SuppressWarnings("AddressSelection")
+ InetAddress addr = InetAddress.getByName(in.nextString());
+ return addr;
}
@Override
public void write(JsonWriter out, InetAddress value) throws IOException {
diff --git a/gson/src/main/java/com/google/gson/stream/JsonReader.java b/gson/src/main/java/com/google/gson/stream/JsonReader.java
index de7aef5ff5..baad1166ca 100644
--- a/gson/src/main/java/com/google/gson/stream/JsonReader.java
+++ b/gson/src/main/java/com/google/gson/stream/JsonReader.java
@@ -16,6 +16,9 @@
package com.google.gson.stream;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.Strictness;
import com.google.gson.internal.JsonReaderInternalAccess;
import com.google.gson.internal.TroubleshootingGuide;
import com.google.gson.internal.bind.JsonTreeReader;
@@ -27,7 +30,7 @@
import java.util.Objects;
/**
- * Reads a JSON (RFC 7159 )
+ * Reads a JSON (RFC 8259 )
* encoded value as a stream of tokens. This stream includes both literal
* values (strings, numbers, booleans, and nulls) as well as the begin and
* end delimiters of objects and arrays. The tokens are traversed in
@@ -63,6 +66,16 @@
* Null literals can be consumed using either {@link #nextNull()} or {@link
* #skipValue()}.
*
+ *
Configuration
+ * The behavior of this reader can be customized with the following methods:
+ *
+ * {@link #setStrictness(Strictness)}, the default is {@link Strictness#LEGACY_STRICT}
+ *
+ *
+ * The default configuration of {@code JsonReader} instances used internally by
+ * the {@link Gson} class differs, and can be adjusted with the various
+ * {@link GsonBuilder} methods.
+ *
* Example
* Suppose we'd like to parse a stream of messages such as the following: {@code
* [
@@ -181,7 +194,7 @@
* Prefixing JSON files with ")]}'\n"
makes them non-executable
* by {@code