Class JsonWriter

java.lang.Object
com.google.gson.stream.JsonWriter
All Implemented Interfaces:
Closeable, Flushable, AutoCloseable
Direct Known Subclasses:
JsonTreeWriter

public class JsonWriter extends Object implements Closeable, Flushable
Writes a JSON (RFC 8259) encoded value to a stream, one token at a time. The stream includes both literal values (strings, numbers, booleans and nulls) as well as the begin and end delimiters of objects and arrays.

Encoding JSON

To encode your data as JSON, create a new JsonWriter. Call methods on the writer as you walk the structure's contents, nesting arrays and objects as necessary:

Configuration

The behavior of this writer can be customized with the following methods: The default configuration of JsonWriter instances used internally by the Gson class differs, and can be adjusted with the various GsonBuilder methods.

Example

Suppose we'd like to encode a stream of messages such as the following:

 [
   {
     "id": 912345678901,
     "text": "How do I stream JSON in Java?",
     "geo": null,
     "user": {
       "name": "json_newb",
       "followers_count": 41
      }
   },
   {
     "id": 912345678902,
     "text": "@json_newb just use JsonWriter!",
     "geo": [50.454722, -104.606667],
     "user": {
       "name": "jesse",
       "followers_count": 2
     }
   }
 ]
 
This code encodes the above structure:

 public void writeJsonStream(OutputStream out, List<Message> messages) throws IOException {
   JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
   writer.setIndent("    ");
   writeMessagesArray(writer, messages);
   writer.close();
 }

 public void writeMessagesArray(JsonWriter writer, List<Message> messages) throws IOException {
   writer.beginArray();
   for (Message message : messages) {
     writeMessage(writer, message);
   }
   writer.endArray();
 }

 public void writeMessage(JsonWriter writer, Message message) throws IOException {
   writer.beginObject();
   writer.name("id").value(message.getId());
   writer.name("text").value(message.getText());
   if (message.getGeo() != null) {
     writer.name("geo");
     writeDoublesArray(writer, message.getGeo());
   } else {
     writer.name("geo").nullValue();
   }
   writer.name("user");
   writeUser(writer, message.getUser());
   writer.endObject();
 }

 public void writeUser(JsonWriter writer, User user) throws IOException {
   writer.beginObject();
   writer.name("name").value(user.getName());
   writer.name("followers_count").value(user.getFollowersCount());
   writer.endObject();
 }

 public void writeDoublesArray(JsonWriter writer, List<Double> doubles) throws IOException {
   writer.beginArray();
   for (Double value : doubles) {
     writer.value(value);
   }
   writer.endArray();
 }
 

Each JsonWriter may be used to write a single JSON stream. Instances of this class are not thread safe. Calls that would result in a malformed JSON string will fail with an IllegalStateException.

Since:
1.6
  • Field Details

    • VALID_JSON_NUMBER_PATTERN

      private static final Pattern VALID_JSON_NUMBER_PATTERN
    • REPLACEMENT_CHARS

      private static final String[] REPLACEMENT_CHARS
    • HTML_SAFE_REPLACEMENT_CHARS

      private static final String[] HTML_SAFE_REPLACEMENT_CHARS
    • out

      private final Writer out
      The JSON output destination
    • stack

      private int[] stack
    • stackSize

      private int stackSize
    • formattingStyle

      private FormattingStyle formattingStyle
    • formattedColon

      private String formattedColon
    • formattedComma

      private String formattedComma
    • usesEmptyNewlineAndIndent

      private boolean usesEmptyNewlineAndIndent
    • strictness

      private Strictness strictness
    • htmlSafe

      private boolean htmlSafe
    • deferredName

      private String deferredName
    • serializeNulls

      private boolean serializeNulls
  • Constructor Details

    • JsonWriter

      public JsonWriter(Writer out)
      Creates a new instance that writes a JSON-encoded stream to out. For best performance, ensure Writer is buffered; wrapping in BufferedWriter if necessary.
  • Method Details

    • setIndent

      public final void setIndent(String indent)
      Sets the indentation string to be repeated for each level of indentation in the encoded document. If indent.isEmpty() the encoded document will be compact. Otherwise the encoded document will be more human-readable.

      This is a convenience method which overwrites any previously set formatting style with either FormattingStyle.COMPACT if the given indent string is empty, or FormattingStyle.PRETTY with the given indent if not empty.

      Parameters:
      indent - a string containing only whitespace.
    • setFormattingStyle

      public final void setFormattingStyle(FormattingStyle formattingStyle)
      Sets the formatting style to be used in the encoded document.

      The formatting style specifies for example the indentation string to be repeated for each level of indentation, or the newline style, to accommodate various OS styles.

      Parameters:
      formattingStyle - the formatting style to use, must not be null.
      Since:
      2.11.0
      See Also:
    • getFormattingStyle

      public final FormattingStyle getFormattingStyle()
      Returns the pretty printing style used by this writer.
      Returns:
      the FormattingStyle that will be used.
      Since:
      2.11.0
      See Also:
    • setLenient

      @Deprecated public final void setLenient(boolean lenient)
      Deprecated.
      Please use setStrictness(Strictness) instead. JsonWriter.setLenient(true) should be replaced by JsonWriter.setStrictness(Strictness.LENIENT) and JsonWriter.setLenient(false) should be replaced by JsonWriter.setStrictness(Strictness.LEGACY_STRICT).
      However, if you used setLenient(false) before, you might prefer Strictness.STRICT now instead.
      Sets the strictness of this writer.
      Parameters:
      lenient - whether this writer should be lenient. If true, the strictness is set to Strictness.LENIENT. If false, the strictness is set to Strictness.LEGACY_STRICT.
      See Also:
    • isLenient

      public boolean isLenient()
      Returns true if the Strictness of this writer is equal to Strictness.LENIENT.
      See Also:
    • setStrictness

      public final void setStrictness(Strictness strictness)
      Configures how strict this writer is with regard to the syntax rules specified in RFC 8259. By default, Strictness.LEGACY_STRICT is used.
      Strictness.STRICT & Strictness.LEGACY_STRICT
      The behavior of these is currently identical. In these strictness modes, the writer only writes JSON in accordance with RFC 8259.
      Strictness.LENIENT
      This mode relaxes the behavior of the writer to allow the writing of NaNs and infinities. It also allows writing multiple top level values.
      Parameters:
      strictness - the new strictness of this writer. May not be null.
      Since:
      2.11.0
      See Also:
    • getStrictness

      public final Strictness getStrictness()
      Returns the strictness of this writer.
      Since:
      2.11.0
      See Also:
    • setHtmlSafe

      public final void setHtmlSafe(boolean htmlSafe)
      Configures this writer to emit JSON that's safe for direct inclusion in HTML and XML documents. This escapes the HTML characters <, >, &, = and ' before writing them to the stream. Without this setting, your XML/HTML encoder should replace these characters with the corresponding escape sequences.
      See Also:
    • isHtmlSafe

      public final boolean isHtmlSafe()
      Returns true if this writer writes JSON that's safe for inclusion in HTML and XML documents.
      See Also:
    • setSerializeNulls

      public final void setSerializeNulls(boolean serializeNulls)
      Sets whether object members are serialized when their value is null. This has no impact on array elements. The default is true.
      See Also:
    • getSerializeNulls

      public final boolean getSerializeNulls()
      Returns true if object members are serialized when their value is null. This has no impact on array elements. The default is true.
      See Also:
    • beginArray

      public JsonWriter beginArray() throws IOException
      Begins encoding a new array. Each call to this method must be paired with a call to endArray().
      Returns:
      this writer.
      Throws:
      IOException
    • endArray

      public JsonWriter endArray() throws IOException
      Ends encoding the current array.
      Returns:
      this writer.
      Throws:
      IOException
    • beginObject

      public JsonWriter beginObject() throws IOException
      Begins encoding a new object. Each call to this method must be paired with a call to endObject().
      Returns:
      this writer.
      Throws:
      IOException
    • endObject

      public JsonWriter endObject() throws IOException
      Ends encoding the current object.
      Returns:
      this writer.
      Throws:
      IOException
    • openScope

      private JsonWriter openScope(int empty, char openBracket) throws IOException
      Enters a new scope by appending any necessary whitespace and the given bracket.
      Throws:
      IOException
    • closeScope

      private JsonWriter closeScope(int empty, int nonempty, char closeBracket) throws IOException
      Closes the current scope by appending any necessary whitespace and the given bracket.
      Throws:
      IOException
    • push

      private void push(int newTop)
    • peek

      private int peek()
      Returns the value on the top of the stack.
    • replaceTop

      private void replaceTop(int topOfStack)
      Replace the value on the top of the stack with the given value.
    • name

      public JsonWriter name(String name) throws IOException
      Encodes the property name.
      Parameters:
      name - the name of the forthcoming value. May not be null.
      Returns:
      this writer.
      Throws:
      IOException
    • writeDeferredName

      private void writeDeferredName() throws IOException
      Throws:
      IOException
    • value

      public JsonWriter value(String value) throws IOException
      Encodes value.
      Parameters:
      value - the literal string value, or null to encode a null literal.
      Returns:
      this writer.
      Throws:
      IOException
    • value

      public JsonWriter value(boolean value) throws IOException
      Encodes value.
      Returns:
      this writer.
      Throws:
      IOException
    • value

      public JsonWriter value(Boolean value) throws IOException
      Encodes value.
      Returns:
      this writer.
      Throws:
      IOException
      Since:
      2.7
    • value

      public JsonWriter value(float value) throws IOException
      Encodes value.
      Parameters:
      value - a finite value, or if lenient, also NaN or infinity.
      Returns:
      this writer.
      Throws:
      IllegalArgumentException - if the value is NaN or Infinity and this writer is not lenient.
      IOException
      Since:
      2.9.1
    • value

      public JsonWriter value(double value) throws IOException
      Encodes value.
      Parameters:
      value - a finite value, or if lenient, also NaN or infinity.
      Returns:
      this writer.
      Throws:
      IllegalArgumentException - if the value is NaN or Infinity and this writer is not lenient.
      IOException
    • value

      public JsonWriter value(long value) throws IOException
      Encodes value.
      Returns:
      this writer.
      Throws:
      IOException
    • value

      public JsonWriter value(Number value) throws IOException
      Encodes value. The value is written by directly writing the Object.toString() result to JSON. Implementations must make sure that the result represents a valid JSON number.
      Parameters:
      value - a finite value, or if lenient, also NaN or infinity.
      Returns:
      this writer.
      Throws:
      IllegalArgumentException - if the value is NaN or Infinity and this writer is not lenient; or if the toString() result is not a valid JSON number.
      IOException
    • nullValue

      public JsonWriter nullValue() throws IOException
      Encodes null.
      Returns:
      this writer.
      Throws:
      IOException
    • jsonValue

      public JsonWriter jsonValue(String value) throws IOException
      Writes value directly to the writer without quoting or escaping. This might not be supported by all implementations, if not supported an UnsupportedOperationException is thrown.
      Parameters:
      value - the literal string value, or null to encode a null literal.
      Returns:
      this writer.
      Throws:
      UnsupportedOperationException - if this writer does not support writing raw JSON values.
      IOException
      Since:
      2.4
    • flush

      public void flush() throws IOException
      Ensures all buffered data is written to the underlying Writer and flushes that writer.
      Specified by:
      flush in interface Flushable
      Throws:
      IOException
    • close

      public void close() throws IOException
      Flushes and closes this writer and the underlying Writer.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException - if the JSON document is incomplete.
    • alwaysCreatesValidJsonNumber

      private static boolean alwaysCreatesValidJsonNumber(Class<? extends Number> c)
      Returns whether the toString() of c will always return a valid JSON number.
    • string

      private void string(String value) throws IOException
      Throws:
      IOException
    • newline

      private void newline() throws IOException
      Throws:
      IOException
    • beforeName

      private void beforeName() throws IOException
      Inserts any necessary separators and whitespace before a name. Also adjusts the stack to expect the name's value.
      Throws:
      IOException
    • beforeValue

      private void beforeValue() throws IOException
      Inserts any necessary separators and whitespace before a literal value, inline array, or inline object. Also adjusts the stack to expect either a closing bracket or another element.
      Throws:
      IOException