diff --git a/Troubleshooting.md b/Troubleshooting.md
index 184f19166e..6bf2b8579a 100644
--- a/Troubleshooting.md
+++ b/Troubleshooting.md
@@ -127,7 +127,7 @@ For example, let's assume you want to deserialize the following JSON data:
}
```
-This will fail with an exception similar to this one: `MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 5 column 4 path $.languages[2]`
+This will fail with an exception similar to this one: `MalformedJsonException: Use JsonReader.setStrictness(Strictness.LENIENT) to accept malformed JSON at line 5 column 4 path $.languages[2]`
The problem here is the trailing comma (`,`) after `"French"`, trailing commas are not allowed by the JSON specification. The location information "line 5 column 4" points to the `]` in the JSON data (with some slight inaccuracies) because Gson expected another value after `,` instead of the closing `]`. The JSONPath `$.languages[2]` in the exception message also points there: `$.` refers to the root object, `languages` refers to its member of that name and `[2]` refers to the (missing) third value in the JSON array value of that member (numbering starts at 0, so it is `[2]` instead of `[3]`).
The proper solution here is to fix the malformed JSON data.
@@ -147,9 +147,12 @@ To spot syntax errors in the JSON data easily you can open it in an editor with
**Reason:** Due to legacy reasons Gson performs parsing by default in lenient mode
-**Solution:** See [`Gson` class documentation](https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/Gson.html#default-lenient) section "Lenient JSON handling"
-
-Note: Even in non-lenient mode Gson deviates slightly from the JSON specification, see [`JsonReader.setLenient`](https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/stream/JsonReader.html#setLenient(boolean)) for more details.
+**Solution:** If you are using Gson 2.11.0 or newer, call [`GsonBuilder.setStrictness`](https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/GsonBuilder.html#setStrictness(com.google.gson.Strictness)),
+[`JsonReader.setStrictness`](https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/stream/JsonReader.html#setStrictness(com.google.gson.Strictness))
+and [`JsonWriter.setStrictness`](https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/stream/JsonWriter.html#setStrictness(com.google.gson.Strictness))
+with `Strictness.STRICT` to overwrite the default lenient behavior of `Gson` and make these classes strictly adhere to the JSON specification.
+Otherwise if you are using an older Gson version, see the [`Gson` class documentation](https://www.javadoc.io/doc/com.google.code.gson/gson/latest/com.google.gson/com/google/gson/Gson.html#default-lenient)
+section "JSON Strictness handling" for alternative solutions.
## `IllegalStateException`: "Expected ... but was ..."
diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java
index c6f8508ef1..0219c1a186 100644
--- a/gson/src/main/java/com/google/gson/Gson.java
+++ b/gson/src/main/java/com/google/gson/Gson.java
@@ -105,10 +105,14 @@
*
See the Gson User Guide
* for a more complete set of examples.
*
- *
Lenient JSON handling
+ *
JSON Strictness handling
* For legacy reasons most of the {@code Gson} methods allow JSON data which does not
- * comply with the JSON specification, regardless of whether {@link GsonBuilder#setLenient()}
- * is used or not. If this behavior is not desired, the following workarounds can be used:
+ * comply with the JSON specification when no explicit {@linkplain Strictness strictness} is set (the default).
+ * To specify the strictness of a {@code Gson} instance, you should set it through
+ * {@link GsonBuilder#setStrictness(Strictness)}.
+ *
+ *
For older Gson versions, which don't have the strictness mode API, the following
+ * workarounds can be used:
*
*
Serialization
*
@@ -132,6 +136,10 @@
* to make sure there is no trailing data
*
*
+ * Note that the {@code JsonReader} created this way is only 'legacy strict', it mostly adheres
+ * to the JSON specification but allows small deviations. See {@link JsonReader#setStrictness(Strictness)}
+ * for details.
+ *
* @see TypeToken
*
* @author Inderjeet Singh
@@ -140,7 +148,8 @@
*/
public final class Gson {
static final boolean DEFAULT_JSON_NON_EXECUTABLE = false;
- static final boolean DEFAULT_LENIENT = false;
+ // Strictness of `null` is the legacy mode where some Gson APIs are always lenient
+ static final Strictness DEFAULT_STRICTNESS = null;
static final FormattingStyle DEFAULT_FORMATTING_STYLE = FormattingStyle.COMPACT;
static final boolean DEFAULT_ESCAPE_HTML = true;
static final boolean DEFAULT_SERIALIZE_NULLS = false;
@@ -184,7 +193,7 @@ public final class Gson {
final boolean generateNonExecutableJson;
final boolean htmlSafe;
final FormattingStyle formattingStyle;
- final boolean lenient;
+ final Strictness strictness;
final boolean serializeSpecialFloatingPointValues;
final boolean useJdkUnsafe;
final String datePattern;
@@ -231,13 +240,15 @@ public final class Gson {
*
By default, Gson excludes transient or static fields from
* consideration for serialization and deserialization. You can change this behavior through
* {@link GsonBuilder#excludeFieldsWithModifiers(int...)}.
+ *
No explicit strictness is set. You can change this by calling
+ * {@link GsonBuilder#setStrictness(Strictness)}.
* 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