Package com.cedarsoftware.io
Class JsonWriter
java.lang.Object
com.cedarsoftware.io.JsonWriter
- All Implemented Interfaces:
WriterContext,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
License
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 interfaceImplement this interface to customize the JSON output for a given class. -
Constructor Summary
ConstructorsConstructorDescriptionJsonWriter(OutputStream out) JsonWriter(OutputStream out, WriteOptions writeOptions) -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()static booleanEnsure that all keys within the Map are String instancesvoidflush()Map containing all objects that were referenced within input object graph.Map containing all objects that were visited within input object graphGets the write options for the current serializationvoidnewLine()Add newline (\n) to outputprotected voidprocessFields(Deque<Object[]> stack, Object obj, int depth) Reach-ability trace to visit all objects within the graph to be written.voidtabIn()Tab the output left (less indented)voidtabOut()Tab the output right (more indented)protected voidtraceReferences(Object root) Walk object graph and visit each instance, following each field, each Collection, Map and so on.voidWrite the passed in Java object in JSON format.booleanwriteArrayElementIfMatching(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 custom writer for the class of the instance 'o'.voidwriteArrayFieldStart(String name) Writes a complete JSON array field start with automatic comma handling.static voidwriteBasicString(Writer writer, String s) Writes out a string without special characters.voidwriteBooleanField(String name, boolean value) Writes a complete JSON boolean field with automatic comma handling.protected booleanwriteCustom(Class<?> clazz, Object o, boolean showType, Writer output) Perform the actual custom writing for an array element that has a custom writer.voidWrites a JSON array closing bracket.voidWrites a JSON object closing brace.voidwriteFieldName(String name) Writes a JSON field name followed by a colon.voidMain entry point (mostly used internally, but may be called from a Custom JSON writer).static voidwriteJsonUtf8String(Writer output, String s) Writes a JSON string value to the output, properly escaped according to JSON specifications.static voidwriteJsonUtf8String(Writer output, String s, int maxStringLength) Writes a JSON string value to the output, properly escaped according to JSON specifications.voidwriteNumberField(String name, Number value) Writes a complete JSON number field with automatic comma handling.voidwriteObject(Object obj, boolean showType, boolean bodyOnly) Allows you to use the current JsonWriter to write an object out.voidwriteObjectField(String name, Object value) Writes a complete JSON object field with automatic serialization and comma handling.voidwriteObjectFieldStart(String name) Writes a complete JSON object field start with automatic comma handling.voidWrites a JSON array opening bracket.voidWrites a JSON object opening brace.voidwriteStringField(String name, String value) Writes a complete JSON string field with automatic comma handling.booleanwriteUsingCustomWriter(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).voidwriteValue(Object value) Writes a JSON value by serializing the given object.voidwriteValue(String value) Writes a JSON string value with proper quote escaping.
-
Constructor Details
-
JsonWriter
- Parameters:
out- OutputStream to which the JSON will be written. Uses the default WriteOptions.- See Also:
-
JsonWriter
- Parameters:
out- OutputStream to which the JSON output will be written.writeOptions- WriteOptions containing many feature options to control the JSON output. Can be null, in which case the default WriteOptions will be used.- See Also:
-
-
Method Details
-
getWriteOptions
Description copied from interface:WriterContextGets the write options for the current serialization- Specified by:
getWriteOptionsin interfaceWriterContext- Returns:
- WriteOptions
-
getObjVisited
Map containing all objects that were visited within input object graph -
getObjsReferenced
Map containing all objects that were referenced within input object graph.- Specified by:
getObjsReferencedin interfaceWriterContext
-
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 custom 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<?> clazz, Object o, boolean showType, Writer output) throws IOException Perform the actual custom writing for an array element that has a custom writer.- Parameters:
clazz- 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
-
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.
-
processFields
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 includedFields 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 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.- Specified by:
writeImplin interfaceWriterContext- Parameters:
obj- Object to be writtenshowType- if set to true, the @type tag will be output.- 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
Description copied from interface:WriterContextAllows you to use the current JsonWriter to write an object out.- Specified by:
writeObjectin interfaceWriterContext- 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.
-
flush
public void flush() -
close
public void close()- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable
-
writeBasicString
Writes out a string without special characters. Use for labels, etc. when you know you will not need extra formattting for UTF-8 or tabs, quotes and newlines in the string- Parameters:
writer- Writer to which the UTF-8 string will be written tos- String to be written in UTF-8 format on the output stream.- Throws:
IOException- if an error occurs writing to the output stream.
-
writeJsonUtf8String
Writes a JSON string value to the output, properly escaped according to JSON specifications. Handles control characters, quotes, backslashes, and properly processes Unicode code points. Uses default string length limit for backward compatibility.- Parameters:
output- The Writer to write tos- The string to be written as a JSON string value- Throws:
IOException- If an I/O error occurs
-
writeJsonUtf8String
public static void writeJsonUtf8String(Writer output, String s, int maxStringLength) throws IOException Writes a JSON string value to the output, properly escaped according to JSON specifications. Handles control characters, quotes, backslashes, and properly processes Unicode code points.- Parameters:
output- The Writer to write tos- The string to be written as a JSON string valuemaxStringLength- Maximum allowed string length to prevent memory issues- Throws:
IOException- If an I/O error occurs
-
writeFieldName
Writes a JSON field name followed by a colon. Example: writeFieldName("name") produces "name": Automatically writes a comma before the field name if this is not the first field.- Specified by:
writeFieldNamein interfaceWriterContext- Parameters:
name- the field name to write (without quotes)- Throws:
IOException- if an I/O error occurs
-
writeStringField
Writes a complete JSON string field with automatic comma handling. Example: writeStringField("name", "John") produces ,"name":"John" This method writes a LEADING comma, making it suitable for fields after the first field. For the first field in an object, either omit the comma manually or use writeFieldName() followed by the value.- Specified by:
writeStringFieldin interfaceWriterContext- Parameters:
name- the field namevalue- the string value (may be null)- Throws:
IOException- if an I/O error occurs
-
writeObjectField
Writes a complete JSON object field with automatic serialization and comma handling. Example: writeObjectField("address", addressObj) produces ,"address":{...} This method writes a LEADING comma, making it suitable for fields after the first field. For the first field in an object, either omit the comma manually or use writeFieldName() followed by writeImpl().- Specified by:
writeObjectFieldin interfaceWriterContext- Parameters:
name- the field namevalue- the object to serialize (may be null)- Throws:
IOException- if an I/O error occurs
-
writeStartObject
Writes a JSON object opening brace. Automatically writes a comma if needed based on context.- Specified by:
writeStartObjectin interfaceWriterContext- Throws:
IOException- if an I/O error occurs- See Also:
-
writeEndObject
Writes a JSON object closing brace. Pops the object context from the stack.- Specified by:
writeEndObjectin interfaceWriterContext- Throws:
IOException- if an I/O error occurs- See Also:
-
writeStartArray
Writes a JSON array opening bracket. Automatically writes a comma if needed based on context.- Specified by:
writeStartArrayin interfaceWriterContext- Throws:
IOException- if an I/O error occurs- See Also:
-
writeEndArray
Writes a JSON array closing bracket. Pops the array context from the stack.- Specified by:
writeEndArrayin interfaceWriterContext- Throws:
IOException- if an I/O error occurs- See Also:
-
writeValue
Writes a JSON string value with proper quote escaping. Example: writeValue("Hello") produces "Hello" Automatically writes a comma if this is an array element and not the first element.- Specified by:
writeValuein interfaceWriterContext- Parameters:
value- the string value to write (may be null)- Throws:
IOException- if an I/O error occurs
-
writeValue
Writes a JSON value by serializing the given object. Example: writeValue(myObject) produces the full JSON representation Automatically writes a comma if this is an array element and not the first element.- Specified by:
writeValuein interfaceWriterContext- Parameters:
value- the object to serialize (may be null)- Throws:
IOException- if an I/O error occurs
-
writeArrayFieldStart
Writes a complete JSON array field start with automatic comma handling. Example: writeArrayFieldStart("items") produces ,"items":[ Manages context by marking the object field written and pushing array context.- Specified by:
writeArrayFieldStartin interfaceWriterContext- Parameters:
name- the field name- Throws:
IOException- if an I/O error occurs
-
writeObjectFieldStart
Writes a complete JSON object field start with automatic comma handling. Example: writeObjectFieldStart("config") produces ,"config":{ Manages context by marking the object field written and pushing object context.- Specified by:
writeObjectFieldStartin interfaceWriterContext- Parameters:
name- the field name- Throws:
IOException- if an I/O error occurs
-
writeNumberField
Writes a complete JSON number field with automatic comma handling. Example: writeNumberField("count", 42) produces ,"count":42- Specified by:
writeNumberFieldin interfaceWriterContext- Parameters:
name- the field namevalue- the number value (may be null)- Throws:
IOException- if an I/O error occurs
-
writeBooleanField
Writes a complete JSON boolean field with automatic comma handling. Example: writeBooleanField("active", true) produces ,"active":true- Specified by:
writeBooleanFieldin interfaceWriterContext- Parameters:
name- the field namevalue- the boolean value- Throws:
IOException- if an I/O error occurs
-