Package com.cedarsoftware.util.io
Class JsonWriter
java.lang.Object
com.cedarsoftware.util.io.JsonWriter
- All Implemented Interfaces:
Closeable
,Flushable
,AutoCloseable
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.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interface
Implement this interface to customize the JSON output for a given class.static interface
Deprecated.static interface
Deprecated. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final String
If set, use the specified ClassLoaderstatic final String
If set, this maps class ==> CustomWriterstatic final String
Set the date format to use within the JSON outputstatic final String
If set, indicates that private variables of ENUMs are not to be serializedstatic final String
Set value to a Map<Class, List> which will be used to control which fields on a class are not output. static final String
Set value to a Map<Class, List> which will be used to control which fields on a class are output static final String
If set to true all maps are transferred to the format @keys[],@items[] regardless of the key_typestatic final String
Constant for use as DATE_FORMAT valuestatic final String
Constant for use as DATE_FORMAT valuestatic final String
Starting Arguments holds onto JsonWriter for custom writers using this argumentstatic final String
If set, this maps class ==> CustomWriterstatic final com.cedarsoftware.util.io.JsonWriter.NullClass
static final String
Force nicely formatted JSON outputstatic final String
If set, then @type -> @t, @keys -> @k, @items -> @istatic final String
If set, null fields are not writtenstatic final String
Force @type alwaysstatic final String
If set, this map will be used when writing @type values - allows shorthand abbreviations type namesstatic final String
If set, longs are written in quotes (Javascript safe) -
Constructor Summary
ConstructorsConstructorDescriptionJsonWriter
(OutputStream out) JsonWriter
(OutputStream out, WriteOptions writeOptions) JsonWriter
(OutputStream out, Map<String, Object> optionalArgs) Deprecated. -
Method Summary
Modifier and TypeMethodDescriptionvoid
addNotCustomWriter
(Class<?> c) For no custom writing to occur for the passed in Class.static void
Adds in Classes that are statically initialized with a possible sun.* class implementation beneath the scenes.static void
addWriterPermanent
(Class<?> c, JsonWriter.JsonClassWriter writer) Add a permanent Customer Writer (Lifetime of JVM)void
close()
static boolean
Ensure that all keys within the Map are String instancesvoid
flush()
static String
formatJson
(String json) Format the passed in JSON string in a nice, human-readable format.static String
formatJson
(String json, Map readingArgs, Map writingArgs) Format the passed in JSON string in a nice, human-readable format.protected String
getSubstituteTypeName
(String typeName) Used internally to substitute type names.protected String
getSubstituteTypeNameIfExists
(String typeName) Used internally to substitute type names.Get a copy of the writeOptions that are in effect for this instance of the JsonWriter.static boolean
void
newLine()
Add newline (\n) to outputstatic String
objectToJson
(Object item) Deprecated.static String
objectToJson
(Object item, Map<String, Object> optionalArgs) Deprecated.static void
setAllowNanAndInfinity
(boolean lenient) Set the writer to be out of RFC 4627: it will accept "NaN", "-Infinity" and "Infinity" values.void
tabIn()
Tab the output left (less indented)void
tabOut()
Tab the output right (more indented)static String
toJson
(Object item, WriteOptions writeOptions) Convert a Java Object to a JSON String.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.protected void
traceReferences
(Object root) Walk object graph and visit each instance, following each field, each Collection, Map and so on.void
Write the passed in Java object in JSON format.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'.protected boolean
writeCustom
(Class<?> arrayComponentClass, Object o, boolean showType, Writer output) Perform the actual custom writing for an array element that has a custom writer.void
Main entry point (mostly used internally, but may be called from a Custom JSON writer).void
Main entry point (mostly used internally, but may be called from a Custom JSON writer).static void
writeJsonUtf8String
(String s, Writer output) 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.void
writeObject
(Object obj, boolean showType, boolean bodyOnly) void
writeObject
(Object obj, boolean showType, boolean bodyOnly, Set<String> fieldsToExclude) 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).
-
Field Details
-
JSON_WRITER
Starting Arguments holds onto JsonWriter for custom writers using this argument- See Also:
-
CUSTOM_WRITER_MAP
If set, this maps class ==> CustomWriter- See Also:
-
NOT_CUSTOM_WRITER_MAP
If set, this maps class ==> CustomWriter- See Also:
-
DATE_FORMAT
Set the date format to use within the JSON output- See Also:
-
ISO_DATE_FORMAT
Constant for use as DATE_FORMAT value- See Also:
-
ISO_DATE_TIME_FORMAT
Constant for use as DATE_FORMAT value- See Also:
-
TYPE
Force @type always- See Also:
-
PRETTY_PRINT
Force nicely formatted JSON output- See Also:
-
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
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
If set, indicates that private variables of ENUMs are not to be serialized- See Also:
-
WRITE_LONGS_AS_STRINGS
If set, longs are written in quotes (Javascript safe)- See Also:
-
TYPE_NAME_MAP
If set, this map will be used when writing @type values - allows shorthand abbreviations type names- See Also:
-
SHORT_META_KEYS
If set, then @type -> @t, @keys -> @k, @items -> @i- See Also:
-
SKIP_NULL_FIELDS
If set, null fields are not written- See Also:
-
CLASSLOADER
If set, use the specified ClassLoader- See Also:
-
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
-
nullWriter
public static final com.cedarsoftware.util.io.JsonWriter.NullClass nullWriter
-
-
Constructor Details
-
JsonWriter
- Parameters:
out
- OutputStream to which the JSON will be written.- See Also:
-
JsonWriter
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
-
-
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
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
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.- 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.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
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
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
Format the passed in JSON string in a nice, human-readable format.- Parameters:
json
- String input JSONreadingArgs
- (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
Get a copy of the writeOptions that are in effect for this instance of the JsonWriter. -
tabIn
Tab the output left (less indented)- Throws:
IOException
-
newLine
Add newline (\n) to output- Throws:
IOException
-
tabOut
Tab the output right (more indented)- Throws:
IOException
-
writeUsingCustomWriter
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 arrayo
- Object instance to writeshowType
- 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 arrayo
- Object instance to writeshowType
- 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
Add a permanent Customer Writer (Lifetime of JVM)- Parameters:
c
- Class to associate a custom JSON writer toowriter
- JsonClassWriter which implements the appropriate subclass of JsonClassWriter.
-
addNotCustomWriter
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
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
Write the passed in Java object in JSON format.- Parameters:
obj
- Object any Java Object or JsonObject.
-
traceReferences
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 graphspecifiers
- 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
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 writtenshowType
- 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 writtenshowType
- if set to true, the @type tag will be output. If false, it will beallowRef
- 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
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
- Parameters:
obj
- Object to be written in JSON formatshowType
- 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 formatshowType
- 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 objectfieldsToExclude
- 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
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() -
close
public void close()- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
-