Class JsonWriter

java.lang.Object
com.cedarsoftware.util.io.JsonWriter
All Implemented Interfaces:
Closeable, Flushable, AutoCloseable

public class JsonWriter extends Object implements Closeable, Flushable
Output a Java object graph in JSON format. This code handles cyclic references and can serialize any Object graph without requiring a class to be 'Serializable' or have any specific methods on it.
  • Call the static method: JsonWriter.objectToJson(employee). This will convert the passed in 'employee' instance into a JSON String.
  • Using streams:
         JsonWriter writer = new JsonWriter(stream);
         writer.write(employee);
         writer.close();
    This will write the 'employee' object to the passed in OutputStream.

That's it. This can be used as a debugging tool. Output an object graph using the above code. Use the JsonWriter PRETTY_PRINT option to format the JSON to be human-readable.

This will output any object graph deeply (or null). Object references are properly handled. For example, if you had A->B, B->C, and C->A, then A will be serialized with a B object in it, B will be serialized with a C object in it, and then C will be serialized with a reference to A (ref), not a redefinition of A.


Author:
John DeRegnaucourt ([email protected])
Copyright (c) Cedar Software LLC

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
  • Field Details

    • JSON_WRITER

      public static final String JSON_WRITER
      Starting Arguments holds onto JsonWriter for custom writers using this argument
      See Also:
    • CUSTOM_WRITER_MAP

      public static final String CUSTOM_WRITER_MAP
      If set, this maps class ==> CustomWriter
      See Also:
    • NOT_CUSTOM_WRITER_MAP

      public static final String NOT_CUSTOM_WRITER_MAP
      If set, this maps class ==> CustomWriter
      See Also:
    • DATE_FORMAT

      public static final String DATE_FORMAT
      Set the date format to use within the JSON output
      See Also:
    • ISO_DATE_FORMAT

      public static final String ISO_DATE_FORMAT
      Constant for use as DATE_FORMAT value
      See Also:
    • ISO_DATE_TIME_FORMAT

      public static final String ISO_DATE_TIME_FORMAT
      Constant for use as DATE_FORMAT value
      See Also:
    • TYPE

      public static final String TYPE
      Force @type always
      See Also:
    • PRETTY_PRINT

      public static final String PRETTY_PRINT
      Force nicely formatted JSON output
      See Also:
    • FIELD_SPECIFIERS

      public static final String FIELD_SPECIFIERS
      Set value to a Map<Class, List> which will be used to control which fields on a class are output
      See Also:
    • FIELD_NAME_BLACK_LIST

      public static final String FIELD_NAME_BLACK_LIST
      Set value to a Map<Class, List> which will be used to control which fields on a class are not output. Black list has always priority to FIELD_SPECIFIERS
      See Also:
    • ENUM_PUBLIC_ONLY

      public static final String ENUM_PUBLIC_ONLY
      If set, indicates that private variables of ENUMs are not to be serialized
      See Also:
    • WRITE_LONGS_AS_STRINGS

      public static final String WRITE_LONGS_AS_STRINGS
      If set, longs are written in quotes (Javascript safe)
      See Also:
    • TYPE_NAME_MAP

      public static final String TYPE_NAME_MAP
      If set, this map will be used when writing @type values - allows shorthand abbreviations type names
      See Also:
    • SHORT_META_KEYS

      public static final String SHORT_META_KEYS
      If set, then @type -> @t, @keys -> @k, @items -> @i
      See Also:
    • SKIP_NULL_FIELDS

      public static final String SKIP_NULL_FIELDS
      If set, null fields are not written
      See Also:
    • CLASSLOADER

      public static final String CLASSLOADER
      If set, use the specified ClassLoader
      See Also:
    • FORCE_MAP_FORMAT_ARRAY_KEYS_ITEMS

      public static final String FORCE_MAP_FORMAT_ARRAY_KEYS_ITEMS
      If set to true all maps are transferred to the format @keys[],@items[] regardless of the key_type
      See Also:
    • EMPTY_SET

      public static final Set<String> EMPTY_SET
    • nullWriter

      public static final com.cedarsoftware.util.io.JsonWriter.NullClass nullWriter
  • Constructor Details

    • JsonWriter

      public JsonWriter(OutputStream out)
      Parameters:
      out - OutputStream to which the JSON will be written.
      See Also:
    • JsonWriter

      @Deprecated public JsonWriter(OutputStream out, Map<String,Object> optionalArgs)
      Deprecated.
      Parameters:
      out - OutputStream to which the JSON output will be written.
      optionalArgs - (optional) Map of extra arguments indicating how dates are formatted, what fields are written out (optional). For Date parameters, use the public static DATE_TIME key, and then use the ISO_DATE or ISO_DATE_TIME indicators. Or you can specify your own custom SimpleDateFormat String, or you can associate a SimpleDateFormat object, in which case it will be used. This setting is for both java.util.Date and java.sql.Date. If the DATE_FORMAT key is not used, then dates will be formatted as longs. This long can be turned back into a date by using 'new Date(longValue)'.

      This method is deprecated, but the constructor that takes OutputStream and a WriteOptions instance instead.

    • JsonWriter

      public JsonWriter(OutputStream out, WriteOptions writeOptions)
  • Method Details

    • isAllowNanAndInfinity

      public static boolean isAllowNanAndInfinity()
      Returns:
      boolean the allowsNanAndInfinity flag
    • setAllowNanAndInfinity

      public static void setAllowNanAndInfinity(boolean lenient)
      Set the writer to be out of RFC 4627: it will accept "NaN", "-Infinity" and "Infinity" values.
      Parameters:
      lenient - boolean true allows Nan and Infinity, -Infinity to be used within JSON.
    • getSubstituteTypeNameIfExists

      protected String getSubstituteTypeNameIfExists(String typeName)
      Used internally to substitute type names. For example, 'java.util.ArrayList, could have a substitute type name of 'alist'. Set substitute type names using the TYPE_NAME_MAP option.
      Parameters:
      typeName - String name of type to substitute.
      Returns:
      String substituted name, or null if there is no substitute.
    • getSubstituteTypeName

      protected String getSubstituteTypeName(String typeName)
      Used internally to substitute type names. For example, 'java.util.ArrayList, could have a substitute type name of 'alist'. Set substitute type names using the TYPE_NAME_MAP option.
      Parameters:
      typeName - String name of type to substitute.
      Returns:
      String substituted type name.
    • objectToJson

      @Deprecated public static String objectToJson(Object item)
      Deprecated.
      Parameters:
      item - Object (root) to serialized to JSON String.
      Returns:
      String of JSON format representing complete object graph rooted by item.
      See Also:
    • objectToJson

      @Deprecated public static String objectToJson(Object item, Map<String,Object> optionalArgs)
      Deprecated.
      Convert a Java Object to a JSON String.
      Parameters:
      item - Object to convert to a JSON String.
      optionalArgs - (optional) Map of extra arguments indicating how dates are formatted, what fields are written out (optional). For Date parameters, use the public static DATE_TIME key, and then use the ISO_DATE or ISO_DATE_TIME indicators. Or you can specify your own custom SimpleDateFormat String, or you can associate a SimpleDateFormat object, in which case it will be used. This setting is for both java.util.Date and java.sql.Date. If the DATE_FORMAT key is not used, then dates will be formatted as longs. This long can be turned back into a date by using 'new Date(longValue)'.
      Returns:
      String containing JSON representation of passed in object root.
    • toJson

      public static String toJson(Object item, WriteOptions writeOptions)
      Convert a Java Object to a JSON String.
      Parameters:
      item - Object to convert to a JSON String.
      writeOptions - (optional can be null for defaults) Map of extra arguments indicating how dates are formatted and what fields are written out (optional). For Date parameters, use the public static DATE_TIME key, and then use the ISO_DATE or ISO_DATE_TIME indicators. Or you can specify your own custom SimpleDateFormat String, or you can associate a SimpleDateFormat object, in which case it will be used. This setting is for both java.util.Date and java.sql.Date. If the DATE_FORMAT key is not used, then dates will be formatted as longs. This long can be turned back into a date by using 'new Date(longValue)'.
      Returns:
      String containing JSON representation of passed in object root.
    • formatJson

      public static String formatJson(String json)
      Format the passed in JSON string in a nice, human-readable format.
      Parameters:
      json - String input JSON
      Returns:
      String containing equivalent JSON, formatted nicely for human readability.
    • formatJson

      public static String formatJson(String json, Map readingArgs, Map writingArgs)
      Format the passed in JSON string in a nice, human-readable format.
      Parameters:
      json - String input JSON
      readingArgs - (optional) Map of extra arguments for parsing json. Can be null.
      writingArgs - (optional) Map of extra arguments for writing out json. Can be null.
      Returns:
      String containing equivalent JSON, formatted nicely for human readability.
    • getWriteOptions

      public WriteOptions getWriteOptions()
      Get a copy of the writeOptions that are in effect for this instance of the JsonWriter.
    • tabIn

      public void tabIn() throws IOException
      Tab the output left (less indented)
      Throws:
      IOException
    • newLine

      public void newLine() throws IOException
      Add newline (\n) to output
      Throws:
      IOException
    • tabOut

      public void tabOut() throws IOException
      Tab the output right (more indented)
      Throws:
      IOException
    • writeUsingCustomWriter

      public boolean writeUsingCustomWriter(Object o, boolean showType, Writer output)
      Write the passed in object (o) to the JSON output stream, if and only if, there is a custom writer associated to the Class of object (o).
      Parameters:
      o - Object to be (potentially written)
      showType - boolean indicating whether to show @type.
      output - Writer where the actual JSON is being written to.
      Returns:
      boolean true if written, false is there is no custom writer for the passed in object.
    • writeArrayElementIfMatching

      public boolean writeArrayElementIfMatching(Class<?> arrayComponentClass, Object o, boolean showType, Writer output)
      Write the passed in array element to the JSON output, if any only if, there is a customer writer for the class of the instance 'o'.
      Parameters:
      arrayComponentClass - Class type of the array
      o - Object instance to write
      showType - boolean indicating whether @type should be output.
      output - Writer to write the JSON to (if there is a custom writer for o's Class).
      Returns:
      true if the array element was written, false otherwise.
    • writeCustom

      protected boolean writeCustom(Class<?> arrayComponentClass, Object o, boolean showType, Writer output) throws IOException
      Perform the actual custom writing for an array element that has a custom writer.
      Parameters:
      arrayComponentClass - Class type of the array
      o - Object instance to write
      showType - boolean indicating whether @type should be output.
      output - Writer to write the JSON to (if there is a custom writer for o's Class).
      Returns:
      true if the array element was written, false otherwise.
      Throws:
      IOException
    • addWriterPermanent

      public static void addWriterPermanent(Class<?> c, JsonWriter.JsonClassWriter writer)
      Add a permanent Customer Writer (Lifetime of JVM)
      Parameters:
      c - Class to associate a custom JSON writer too
      writer - JsonClassWriter which implements the appropriate subclass of JsonClassWriter.
    • addNotCustomWriter

      public void addNotCustomWriter(Class<?> c)
      For no custom writing to occur for the passed in Class.
      Parameters:
      c - Class which should NOT have any custom writer associated to it. Use this to prevent a custom writer from being used due to inheritance.
    • addStaticallyInitializedClasses

      public static void addStaticallyInitializedClasses(Class<?> c)
      Adds in Classes that are statically initialized with a possible sun.* class implementation beneath the scenes. These classes will never match their Field declaration and will usually cause the writer to show the @Type. Adding to this class and providing a custom writer and reader gives you the power to eliminate the type in those cases and possibly provide a primitive writer/reader.
      Parameters:
      c - Class that has custom writer implementation and will never match declared field.
    • write

      public void write(Object obj)
      Write the passed in Java object in JSON format.
      Parameters:
      obj - Object any Java Object or JsonObject.
    • traceReferences

      protected void traceReferences(Object root)
      Walk object graph and visit each instance, following each field, each Collection, Map and so on. Tracks visited to handle cycles and to determine if an item is referenced elsewhere. If an object is never referenced more than once, no @id field needs to be emitted for it.
      Parameters:
      root - Object to be deeply traced. The objVisited and objsReferenced Maps will be written to during the trace.
    • traceFields

      protected void traceFields(Deque<Object> stack, Object obj, Map<Class<?>,Collection<Accessor>> specifiers)
      Reach-ability trace to visit all objects within the graph to be written. This API will handle any object, using either reflection APIs or by consulting a specified FIELD_SPECIFIERS map if provided.
      Parameters:
      stack - Deque used to manage descent into graph (rather than using Java stack.) This allows for much larger graph processing.
      obj - Object root of graph
      specifiers - Map of optional field specifiers, which are used to override the field list returned by the JDK reflection operations. This allows a subset of the actual fields on an object to be serialized.
    • writeImpl

      public void writeImpl(Object obj, boolean showType) throws IOException
      Main entry point (mostly used internally, but may be called from a Custom JSON writer). This method will write out whatever object type it is given, including JsonObject's. It will handle null, detecting if a custom writer should be called, array, array of JsonObject, Map, Map of JsonObjects, Collection, Collection of JsonObject, any regular object, or a JsonObject representing a regular object.
      Parameters:
      obj - Object to be written
      showType - if set to true, the @type tag will be output. If false, it will be dropped.
      Throws:
      IOException - if one occurs on the underlying output stream.
    • writeImpl

      public void writeImpl(Object obj, boolean showType, boolean allowRef, boolean allowCustom) throws IOException
      Main entry point (mostly used internally, but may be called from a Custom JSON writer). This method will write out whatever object type it is given, including JsonObject's. It will handle null, detecting if a custom writer should be called, array, array of JsonObject, Map, Map of JsonObjects, Collection, Collection of JsonObject, any regular object, or a JsonObject representing a regular object.
      Parameters:
      obj - Object to be written
      showType - if set to true, the @type tag will be output. If false, it will be
      allowRef - if set to true, @ref will be used, otherwise 2+ occurrence will be output as full object.
      allowCustom - if set to true, the object being called will be checked for a matching custom writer to be used. This does not affect sub-objects, just the top-level 'obj' being passed in.
      Throws:
      IOException - if one occurs on the underlying output stream.
    • ensureJsonPrimitiveKeys

      public static boolean ensureJsonPrimitiveKeys(Map map)
      Ensure that all keys within the Map are String instances
      Parameters:
      map - Map to inspect that all keys are primitive. This allows the output JSON to be optimized into {"key1":value1, "key2": value2} format if all the keys of the Map are Strings. If not, then a Map is written as two arrays, a @keys array and an @items array. This allows support for Maps with non-String keys.
    • writeObject

      public void writeObject(Object obj, boolean showType, boolean bodyOnly) throws IOException
      Parameters:
      obj - Object to be written in JSON format
      showType - boolean true means show the "@type" field, false eliminates it. Many times the type can be dropped because it can be inferred from the field or array type.
      bodyOnly - write only the body of the object
      Throws:
      IOException - if an error occurs writing to the output stream.
    • writeObject

      public void writeObject(Object obj, boolean showType, boolean bodyOnly, Set<String> fieldsToExclude) throws IOException
      Parameters:
      obj - Object to be written in JSON format
      showType - boolean true means show the "@type" field, false eliminates it. Many times the type can be dropped because it can be inferred from the field or array type.
      bodyOnly - write only the body of the object
      fieldsToExclude - field that should be excluded when writing out object (per class bases for custom writers)
      Throws:
      IOException - if an error occurs writing to the output stream.
    • writeJsonUtf8String

      public static void writeJsonUtf8String(String s, Writer output) throws IOException
      Write out special characters "\b, \f, \t, \n, \r", as such, backslash as \\ quote as \" and values less than an ASCII space (20hex) as "\\u00xx" format, characters in the range of ASCII space to a '~' as ASCII, and anything higher in UTF-8.
      Parameters:
      s - String to be written in UTF-8 format on the output stream.
      output - Writer to which the UTF-8 string will be written to
      Throws:
      IOException - if an error occurs writing to the output stream.
    • flush

      public void flush()
      Specified by:
      flush in interface Flushable
    • close

      public void close()
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable