diff --git a/gson/src/main/java/com/google/gson/JsonArray.java b/gson/src/main/java/com/google/gson/JsonArray.java index 0d1cbd2f17..10b94c0dc1 100644 --- a/gson/src/main/java/com/google/gson/JsonArray.java +++ b/gson/src/main/java/com/google/gson/JsonArray.java @@ -33,6 +33,9 @@ *

{@code JsonArray} only implements the {@link Iterable} interface but not the {@link List} * interface. A {@code List} view of it can be obtained with {@link #asList()}. * + *

See the {@link JsonElement} documentation for details on how to convert {@code JsonArray} and + * generally any {@code JsonElement} from and to JSON. + * * @author Inderjeet Singh * @author Joel Leitch */ diff --git a/gson/src/main/java/com/google/gson/JsonElement.java b/gson/src/main/java/com/google/gson/JsonElement.java index fa3a7af5f6..b7d135b978 100644 --- a/gson/src/main/java/com/google/gson/JsonElement.java +++ b/gson/src/main/java/com/google/gson/JsonElement.java @@ -20,6 +20,7 @@ import com.google.gson.internal.Streams; import com.google.gson.stream.JsonWriter; import java.io.IOException; +import java.io.Reader; import java.io.StringWriter; import java.math.BigDecimal; import java.math.BigInteger; @@ -28,6 +29,69 @@ * A class representing an element of JSON. It could either be a {@link JsonObject}, a {@link * JsonArray}, a {@link JsonPrimitive} or a {@link JsonNull}. * + *

This class provides multiple {@code getAs} methods which allow + * + *

+ * + *

Converting {@code JsonElement} from / to JSON

+ * + * There are two ways to parse JSON data as a {@link JsonElement}: + * + * + * + * To convert a {@code JsonElement} to JSON either {@link #toString() JsonElement.toString()} or the + * method {@link Gson#toJson(JsonElement)} and its overloads can be used. + * + *

It is also possible to obtain the {@link TypeAdapter} for {@code JsonElement} from a {@link + * Gson} instance and then use it for conversion from and to JSON: + * + *

{@code
+ * TypeAdapter adapter = gson.getAdapter(JsonElement.class);
+ *
+ * JsonElement value = adapter.fromJson("{}");
+ * String json = adapter.toJson(value);
+ * }
+ * + *

{@code JsonElement} as JSON data

+ * + * {@code JsonElement} can also be treated as JSON data, allowing to deserialize from a {@code + * JsonElement} and serializing to a {@code JsonElement}. The {@link Gson} class offers these + * methods for this: + * + * + * + * The {@link TypeAdapter} class provides corresponding methods as well: + * + * + * * @author Inderjeet Singh * @author Joel Leitch */ @@ -320,7 +384,41 @@ public short getAsShort() { throw new UnsupportedOperationException(getClass().getSimpleName()); } - /** Returns a String representation of this element. */ + /** + * Converts this element to a JSON string. + * + *

For example: + * + *

+   * JsonObject object = new JsonObject();
+   * object.add("a", JsonNull.INSTANCE);
+   * JsonArray array = new JsonArray();
+   * array.add(1);
+   * object.add("b", array);
+   *
+   * String json = object.toString();
+   * // json: {"a":null,"b":[1]}
+   * 
+ * + * If this element or any nested elements contain {@link Double#NaN NaN} or {@link + * Double#isInfinite() Infinity} that value is written to JSON, even though the JSON specification + * does not permit these values. + * + *

To customize formatting or to directly write to an {@link Appendable} instead of creating an + * intermediate {@code String} first, use {@link Gson#toJson(JsonElement, Appendable) + * Gson.toJson(JsonElement, ...)}. + * + *

To get the contained String value (without enclosing {@code "} and without escaping), use + * {@link #getAsString()} instead: + * + *

+   * JsonPrimitive jsonPrimitive = new JsonPrimitive("with \" quote");
+   * String json = jsonPrimitive.toString();
+   * // json: "with \" quote"
+   * String value = jsonPrimitive.getAsString();
+   * // value: with " quote
+   * 
+ */ @Override public String toString() { try { diff --git a/gson/src/main/java/com/google/gson/JsonObject.java b/gson/src/main/java/com/google/gson/JsonObject.java index d13be19dce..408d22685d 100644 --- a/gson/src/main/java/com/google/gson/JsonObject.java +++ b/gson/src/main/java/com/google/gson/JsonObject.java @@ -22,7 +22,7 @@ import java.util.Set; /** - * A class representing an object type in Json. An object consists of name-value pairs where names + * A class representing an object type in JSON. An object consists of name-value pairs where names * are strings, and values are any other type of {@link JsonElement}. This allows for a creating a * tree of JsonElements. The member elements of this object are maintained in order they were added. * This class does not support {@code null} values. If {@code null} is provided as value argument to @@ -31,6 +31,9 @@ *

{@code JsonObject} does not implement the {@link Map} interface, but a {@code Map} view of it * can be obtained with {@link #asMap()}. * + *

See the {@link JsonElement} documentation for details on how to convert {@code JsonObject} and + * generally any {@code JsonElement} from and to JSON. + * * @author Inderjeet Singh * @author Joel Leitch */ diff --git a/gson/src/main/java/com/google/gson/JsonParser.java b/gson/src/main/java/com/google/gson/JsonParser.java index 09277ec48c..9daf004265 100644 --- a/gson/src/main/java/com/google/gson/JsonParser.java +++ b/gson/src/main/java/com/google/gson/JsonParser.java @@ -50,7 +50,7 @@ * following example demonstrates how to achieve it: * *

- * String json = "{\"skipObj\": {\"skipKey\": \"skipValue\"},\"obj\": {\"key\": \"value\"}}";
+ * String json = "{\"skipObj\": {\"skipKey\": \"skipValue\"}, \"obj\": {\"key\": \"value\"}}";
  * try (JsonReader jsonReader = new JsonReader(new StringReader(json))) {
  *   jsonReader.beginObject();
  *   while (jsonReader.hasNext()) {
diff --git a/gson/src/main/java/com/google/gson/JsonPrimitive.java b/gson/src/main/java/com/google/gson/JsonPrimitive.java
index 2bce4be498..88f4466fc8 100644
--- a/gson/src/main/java/com/google/gson/JsonPrimitive.java
+++ b/gson/src/main/java/com/google/gson/JsonPrimitive.java
@@ -26,6 +26,9 @@
  * A class representing a JSON primitive value. A primitive value is either a String, a Java
  * primitive, or a Java primitive wrapper type.
  *
+ * 

See the {@link JsonElement} documentation for details on how to convert {@code JsonPrimitive} + * and generally any {@code JsonElement} from and to JSON. + * * @author Inderjeet Singh * @author Joel Leitch */ diff --git a/gson/src/test/java/com/google/gson/JsonArrayTest.java b/gson/src/test/java/com/google/gson/JsonArrayTest.java index 30942513fa..a140814464 100644 --- a/gson/src/test/java/com/google/gson/JsonArrayTest.java +++ b/gson/src/test/java/com/google/gson/JsonArrayTest.java @@ -376,4 +376,21 @@ public void testSameAddition() { assertThat(jsonArray.toString()) .isEqualTo("[\"a\",\"a\",true,true,1212,1212,34.34,34.34,null,null]"); } + + @Test + public void testToString() { + JsonArray array = new JsonArray(); + assertThat(array.toString()).isEqualTo("[]"); + + array.add(JsonNull.INSTANCE); + array.add(Float.NaN); + array.add("a\0"); + JsonArray nestedArray = new JsonArray(); + nestedArray.add('"'); + array.add(nestedArray); + JsonObject nestedObject = new JsonObject(); + nestedObject.addProperty("n\0", 1); + array.add(nestedObject); + assertThat(array.toString()).isEqualTo("[null,NaN,\"a\\u0000\",[\"\\\"\"],{\"n\\u0000\":1}]"); + } } diff --git a/gson/src/test/java/com/google/gson/JsonNullTest.java b/gson/src/test/java/com/google/gson/JsonNullTest.java index ca995b925b..d3c5b98cd6 100644 --- a/gson/src/test/java/com/google/gson/JsonNullTest.java +++ b/gson/src/test/java/com/google/gson/JsonNullTest.java @@ -43,4 +43,9 @@ public void testDeepCopy() { assertThat(a.deepCopy()).isSameInstanceAs(JsonNull.INSTANCE); assertThat(JsonNull.INSTANCE.deepCopy()).isSameInstanceAs(JsonNull.INSTANCE); } + + @Test + public void testToString() { + assertThat(JsonNull.INSTANCE.toString()).isEqualTo("null"); + } } diff --git a/gson/src/test/java/com/google/gson/JsonObjectTest.java b/gson/src/test/java/com/google/gson/JsonObjectTest.java index 353fa102d2..da6931c984 100644 --- a/gson/src/test/java/com/google/gson/JsonObjectTest.java +++ b/gson/src/test/java/com/google/gson/JsonObjectTest.java @@ -344,4 +344,21 @@ public void testEntrySet() { assertThat(new ArrayList<>(o.entrySet())).isEqualTo(new ArrayList<>(expectedEntriesQueue)); } } + + @Test + public void testToString() { + JsonObject object = new JsonObject(); + assertThat(object.toString()).isEqualTo("{}"); + + object.add("a", JsonNull.INSTANCE); + object.addProperty("b\0", Float.NaN); + JsonArray nestedArray = new JsonArray(); + nestedArray.add('"'); + object.add("c", nestedArray); + JsonObject nestedObject = new JsonObject(); + nestedObject.addProperty("n\0", 1); + object.add("d", nestedObject); + assertThat(object.toString()) + .isEqualTo("{\"a\":null,\"b\\u0000\":NaN,\"c\":[\"\\\"\"],\"d\":{\"n\\u0000\":1}}"); + } } diff --git a/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java b/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java index 523e1d8b3f..be1e122544 100644 --- a/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java +++ b/gson/src/test/java/com/google/gson/JsonPrimitiveTest.java @@ -260,12 +260,34 @@ public void testDoubleEqualsBigDecimal() { } @Test - public void testValidJsonOnToString() { + public void testToString() { JsonPrimitive json = new JsonPrimitive("Some\nEscaped\nValue"); assertThat(json.toString()).isEqualTo("\"Some\\nEscaped\\nValue\""); + json = new JsonPrimitive(""); + assertThat(json.toString()).isEqualTo("\"\""); + json = new JsonPrimitive(new BigDecimal("1.333")); assertThat(json.toString()).isEqualTo("1.333"); + + // Preserves trailing 0 + json = new JsonPrimitive(new BigDecimal("1.0000")); + assertThat(json.toString()).isEqualTo("1.0000"); + + json = new JsonPrimitive(Float.NaN); + assertThat(json.toString()).isEqualTo("NaN"); + + json = new JsonPrimitive(Double.NEGATIVE_INFINITY); + assertThat(json.toString()).isEqualTo("-Infinity"); + + json = new JsonPrimitive('a'); + assertThat(json.toString()).isEqualTo("\"a\""); + + json = new JsonPrimitive('\0'); + assertThat(json.toString()).isEqualTo("\"\\u0000\""); + + json = new JsonPrimitive(true); + assertThat(json.toString()).isEqualTo("true"); } @Test