Package com.cedarsoftware.util.io
Class JsonReader
- java.lang.Object
-
- com.cedarsoftware.util.io.JsonReader
-
- All Implemented Interfaces:
Closeable
,AutoCloseable
public class JsonReader extends Object implements Closeable
Read an object graph in JSON format and make it available in Java objects, or in a "Map of Maps." (untyped representation). This code handles cyclic references and can deserialize any Object graph without requiring a class to be 'Serializeable' or have any specific methods on it. It will handle classes with non public constructors.
Usages:-
Call the static method:
JsonReader.jsonToJava(String json)
. This will return a typed Java object graph. -
Call the static method:
JsonReader.jsonToMaps(String json)
. This will return an untyped object representation of the JSON String as a Map of Maps, where the fields are the Map keys, and the field values are the associated Map's values. You can call the JsonWriter.objectToJson() method with the returned Map, and it will serialize the Graph into the equivalent JSON stream from which it was read. -
Instantiate the JsonReader with an InputStream:
JsonReader(InputStream in)
and then callreadObject()
. Cast the return value of readObject() to the Java class that was the root of the graph. -
Instantiate the JsonReader with an InputStream:
JsonReader(InputStream in, true)
and then callreadObject()
. The return value will be a Map of Maps.
- 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 Classes Modifier and Type Class Description static interface
JsonReader.ClassFactory
Subclass this interface and create a class that will return a new instance of the passed in Class (c).static interface
JsonReader.ClassFactoryEx
Subclass this interface and create a class that will return a new instance of the passed in Class (c).static class
JsonReader.CollectionFactory
Use to create new instances of collection interfaces (needed for empty collections)static interface
JsonReader.Factory
Common ancestor for ClassFactory and ClassFactoryEx.static interface
JsonReader.JsonClassReader
Implement this interface to add a custom JSON reader.static interface
JsonReader.JsonClassReaderBase
Common ancestor for JsonClassReader and JsonClassReaderEx.static interface
JsonReader.JsonClassReaderEx
Implement this interface to add a custom JSON reader.static class
JsonReader.MapFactory
Use to create new instances of Map interfaces (needed for empty Maps).static interface
JsonReader.MissingFieldHandler
Used to react to fields missing when reading an object.
-
Field Summary
Fields Modifier and Type Field Description static String
CLASSLOADER
If set, use the specified ClassLoaderstatic String
CUSTOM_READER_MAP
If set, this maps class ==> CustomReaderstatic String
FAIL_ON_UNKNOWN_TYPE
Will fail JSON parsing if 'type' class defined but is not on classpath.static String
JSON_READER
Pointer to 'this' (automatically placed in the Map)static String
MISSING_FIELD_HANDLER
If set, this object will be called when a field is present in the JSON but missing from the corresponding classprotected JsonReader.MissingFieldHandler
missingFieldHandler
static String
NOT_CUSTOM_READER_MAP
If set, this indicates that no custom reader should be used for the specified class ==> CustomReaderprotected Set<Class>
notCustom
static String
OBJECT_RESOLVER
Pointer to the current ObjectResolver (automatically placed in the Map)protected Map<Class,JsonReader.JsonClassReaderBase>
readers
static String
TYPE_NAME_MAP
If set, this map will be used when writing @type values - allows short-hand abbreviations type namesstatic String
UNKNOWN_OBJECT
What to do when an object is found and 'type' cannot be determined.static String
USE_MAPS
If set, the read-in JSON will be turned into a Map of Maps (JsonObject) representation
-
Constructor Summary
Constructors Constructor Description JsonReader()
JsonReader(byte[] inp, Map<String,Object> optionalArgs)
JsonReader(byte[] inp, Map<String,Object> optionalArgs, int maxDepth)
JsonReader(int maxDepth)
JsonReader(InputStream inp)
JsonReader(InputStream inp, boolean useMaps)
JsonReader(InputStream inp, boolean useMaps, int maxDepth)
JsonReader(InputStream inp, int maxDepth)
JsonReader(InputStream inp, Map<String,Object> optionalArgs)
JsonReader(InputStream inp, Map<String,Object> optionalArgs, int maxDepth)
JsonReader(String inp, Map<String,Object> optionalArgs)
JsonReader(String inp, Map<String,Object> optionalArgs, int maxDepth)
JsonReader(Map<String,Object> optionalArgs)
Use this constructor if you already have a JsonObject graph and want to parse it into Java objects by calling jsonReader.jsonObjectsToJava(rootJsonObject) after constructing the JsonReader.JsonReader(Map<String,Object> optionalArgs, int maxDepth)
Use this constructor if you already have a JsonObject graph and want to parse it into Java objects by calling jsonReader.jsonObjectsToJava(rootJsonObject) after constructing the JsonReader.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description void
addNotCustomReader(Class c)
Force json-io to use it's internal generic approach to writing the passed in class, even if a Custom JSON reader is specified for its parent class.void
addReader(Class c, JsonReader.JsonClassReaderBase reader)
Call this method to add a custom JSON reader to json-io.static void
addReaderPermanent(Class c, JsonReader.JsonClassReaderBase reader)
Call this method to add a custom JSON reader to json-io.static void
assignInstantiator(Class c, JsonReader.Factory f)
Assign instantiated by Class.static void
assignInstantiator(String n, JsonReader.Factory f)
For difficult to instantiate classes, you can add your own ClassFactory or ClassFactoryEx which will be called when the passed in class 'c' is encountered.void
close()
protected Object
convertParsedMapsToJava(JsonObject root)
This method converts a root Map, (which contains nested Maps and so forth representing a Java Object graph), to a Java object instance.Map<String,Object>
getArgs()
Map<Long,JsonObject>
getObjectsRead()
Object
getRefTarget(JsonObject jObj)
static boolean
isAllowNanAndInfinity()
Object
jsonObjectsToJava(JsonObject root)
Convert a root JsonObject that represents parsed JSON, into an actual Java object.static Object
jsonToJava(InputStream inputStream, Map<String,Object> optionalArgs)
Convert the passed in JSON string into a Java object graph.static Object
jsonToJava(InputStream inputStream, Map<String,Object> optionalArgs, int maxDepth)
Convert the passed in JSON string into a Java object graph.static Object
jsonToJava(String json)
Convert the passed in JSON string into a Java object graph.static Object
jsonToJava(String json, Map<String,Object> optionalArgs)
Convert the passed in JSON string into a Java object graph.static Object
jsonToJava(String json, Map<String,Object> optionalArgs, int maxDepth)
Convert the passed in JSON string into a Java object graph.static Map
jsonToMaps(InputStream inputStream, Map<String,Object> optionalArgs)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(inputStream, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null).static Map
jsonToMaps(InputStream inputStream, Map<String,Object> optionalArgs, int maxDepth)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(inputStream, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null).static Map
jsonToMaps(String json)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(String json, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null).static Map
jsonToMaps(String json, int maxDepth)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(String json, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null).static Map
jsonToMaps(String json, Map<String,Object> optionalArgs)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(String json, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null).static Map
jsonToMaps(String json, Map<String,Object> optionalArgs, int maxDepth)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(String json, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null).static Object
newInstance(Class c)
static Object
newInstance(Class c, JsonObject jsonObject)
Object
readObject()
Read JSON input from the stream that was set up in the constructor, turning it into Java Maps (JsonObject's).static void
setAllowNanAndInfinity(boolean lenient)
Set the reader to be out of RFC 4627: it will accept "NaN", "-Infinity" and "Infinity" values.void
setMissingFieldHandler(JsonReader.MissingFieldHandler handler)
protected boolean
useMaps()
-
-
-
Field Detail
-
CUSTOM_READER_MAP
public static final String CUSTOM_READER_MAP
If set, this maps class ==> CustomReader- See Also:
- Constant Field Values
-
NOT_CUSTOM_READER_MAP
public static final String NOT_CUSTOM_READER_MAP
If set, this indicates that no custom reader should be used for the specified class ==> CustomReader- See Also:
- Constant Field Values
-
USE_MAPS
public static final String USE_MAPS
If set, the read-in JSON will be turned into a Map of Maps (JsonObject) representation- See Also:
- Constant Field Values
-
UNKNOWN_OBJECT
public static final String UNKNOWN_OBJECT
What to do when an object is found and 'type' cannot be determined.- See Also:
- Constant Field Values
-
FAIL_ON_UNKNOWN_TYPE
public static final String FAIL_ON_UNKNOWN_TYPE
Will fail JSON parsing if 'type' class defined but is not on classpath.- See Also:
- Constant Field Values
-
JSON_READER
public static final String JSON_READER
Pointer to 'this' (automatically placed in the Map)- See Also:
- Constant Field Values
-
OBJECT_RESOLVER
public static final String OBJECT_RESOLVER
Pointer to the current ObjectResolver (automatically placed in the Map)- See Also:
- Constant Field Values
-
TYPE_NAME_MAP
public static final String TYPE_NAME_MAP
If set, this map will be used when writing @type values - allows short-hand abbreviations type names- See Also:
- Constant Field Values
-
MISSING_FIELD_HANDLER
public static final String MISSING_FIELD_HANDLER
If set, this object will be called when a field is present in the JSON but missing from the corresponding class- See Also:
- Constant Field Values
-
CLASSLOADER
public static final String CLASSLOADER
If set, use the specified ClassLoader- See Also:
- Constant Field Values
-
readers
protected final Map<Class,JsonReader.JsonClassReaderBase> readers
-
missingFieldHandler
protected JsonReader.MissingFieldHandler missingFieldHandler
-
-
Constructor Detail
-
JsonReader
public JsonReader(int maxDepth)
-
JsonReader
public JsonReader()
-
JsonReader
public JsonReader(InputStream inp, int maxDepth)
-
JsonReader
public JsonReader(InputStream inp)
-
JsonReader
public JsonReader(Map<String,Object> optionalArgs, int maxDepth)
Use this constructor if you already have a JsonObject graph and want to parse it into Java objects by calling jsonReader.jsonObjectsToJava(rootJsonObject) after constructing the JsonReader.- Parameters:
optionalArgs
- Map of optional arguments for the JsonReader.maxDepth
- Maximum parsing depth.
-
JsonReader
public JsonReader(Map<String,Object> optionalArgs)
Use this constructor if you already have a JsonObject graph and want to parse it into Java objects by calling jsonReader.jsonObjectsToJava(rootJsonObject) after constructing the JsonReader.- Parameters:
optionalArgs
- Map of optional arguments for the JsonReader.
-
JsonReader
public JsonReader(InputStream inp, boolean useMaps, int maxDepth)
-
JsonReader
public JsonReader(InputStream inp, boolean useMaps)
-
JsonReader
public JsonReader(InputStream inp, Map<String,Object> optionalArgs, int maxDepth)
-
JsonReader
public JsonReader(InputStream inp, Map<String,Object> optionalArgs)
-
-
Method Detail
-
isAllowNanAndInfinity
public static boolean isAllowNanAndInfinity()
- Returns:
- boolean the allowNanAndInfinity setting
-
setAllowNanAndInfinity
public static void setAllowNanAndInfinity(boolean lenient)
Set the reader to be out of RFC 4627: it will accept "NaN", "-Infinity" and "Infinity" values.- Parameters:
lenient
- the lenient to set
-
assignInstantiator
public static void assignInstantiator(String n, JsonReader.Factory f)
For difficult to instantiate classes, you can add your own ClassFactory or ClassFactoryEx which will be called when the passed in class 'c' is encountered. Your ClassFactory will be called with newInstance(c) and your factory is expected to return a new instance of 'c'. This API is an 'escape hatch' to allow ANY object to be instantiated by JsonReader and is useful when you encounter a class that JsonReader cannot instantiate using its internal exhausting attempts (trying all constructors, varying arguments to them, etc.)- Parameters:
n
- Class name to assign an ClassFactory tof
- ClassFactory that will create 'c' instances
-
assignInstantiator
public static void assignInstantiator(Class c, JsonReader.Factory f)
Assign instantiated by Class. Falls back to JsonReader.assignInstantiator(String, Factory)- Parameters:
c
- Class to assign an ClassFactory tof
- ClassFactory that will create 'c' instances
-
addReader
public void addReader(Class c, JsonReader.JsonClassReaderBase reader)
Call this method to add a custom JSON reader to json-io. It will associate the Class 'c' to the reader you pass in. The readers are found with isAssignableFrom(). If this is too broad, causing too many classes to be associated to the custom reader, you can indicate that json-io should not use a custom reader for a particular class, by calling the addNotCustomReader() method.- Parameters:
c
- Class to assign a custom JSON reader toreader
- The JsonClassReader which will read the custom JSON format of 'c'
-
addReaderPermanent
public static void addReaderPermanent(Class c, JsonReader.JsonClassReaderBase reader)
Call this method to add a custom JSON reader to json-io. It will associate the Class 'c' to the reader you pass in. The readers are found with isAssignableFrom(). If this is too broad, causing too many classes to be associated to the custom reader, you can indicate that json-io should not use a custom reader for a particular class, by calling the addNotCustomReader() method. This method will add the customer reader such that it will be there permanently, for the life of the JVM (static).- Parameters:
c
- Class to assign a custom JSON reader toreader
- The JsonClassReader which will read the custom JSON format of 'c'
-
addNotCustomReader
public void addNotCustomReader(Class c)
Force json-io to use it's internal generic approach to writing the passed in class, even if a Custom JSON reader is specified for its parent class.- Parameters:
c
- Class to which to force no custom JSON reading to occur. Normally, this is not needed, however, if a reader is assigned to a parent class of 'c', then calling this method on 'c' will prevent any custom reader from processing class 'c'
-
setMissingFieldHandler
public void setMissingFieldHandler(JsonReader.MissingFieldHandler handler)
-
getArgs
public Map<String,Object> getArgs()
- Returns:
- The arguments used to configure the JsonReader. These are thread local.
-
jsonToJava
public static Object jsonToJava(String json)
Convert the passed in JSON string into a Java object graph.- Parameters:
json
- String JSON input- Returns:
- Java object graph matching JSON input
-
jsonToJava
public static Object jsonToJava(String json, Map<String,Object> optionalArgs, int maxDepth)
Convert the passed in JSON string into a Java object graph.- Parameters:
json
- String JSON inputoptionalArgs
- Map of optional parameters to control parsing. See readme file for details.maxDepth
- Maximum parsing depth.- Returns:
- Java object graph matching JSON input
-
jsonToJava
public static Object jsonToJava(String json, Map<String,Object> optionalArgs)
Convert the passed in JSON string into a Java object graph.- Parameters:
json
- String JSON inputoptionalArgs
- Map of optional parameters to control parsing. See readme file for details.- Returns:
- Java object graph matching JSON input
-
jsonToJava
public static Object jsonToJava(InputStream inputStream, Map<String,Object> optionalArgs, int maxDepth)
Convert the passed in JSON string into a Java object graph.- Parameters:
inputStream
- InputStream containing JSON inputoptionalArgs
- Map of optional parameters to control parsing. See readme file for details.maxDepth
- Maximum parsing depth.- Returns:
- Java object graph matching JSON input
-
jsonToJava
public static Object jsonToJava(InputStream inputStream, Map<String,Object> optionalArgs)
Convert the passed in JSON string into a Java object graph.- Parameters:
inputStream
- InputStream containing JSON inputoptionalArgs
- Map of optional parameters to control parsing. See readme file for details.- Returns:
- Java object graph matching JSON input
-
jsonToMaps
public static Map jsonToMaps(String json, int maxDepth)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(String json, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null). No longer recommended: Use jsonToJava with USE_MAPS:true- Parameters:
json
- String of JSON contentmaxDeth
- Maximum parsing depth.- Returns:
- Map representing JSON content. Each object is represented by a Map.
-
jsonToMaps
public static Map jsonToMaps(String json)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(String json, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null). No longer recommended: Use jsonToJava with USE_MAPS:true- Parameters:
json
- String of JSON content- Returns:
- Map representing JSON content. Each object is represented by a Map.
-
jsonToMaps
public static Map jsonToMaps(String json, Map<String,Object> optionalArgs, int maxDepth)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(String json, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null). No longer recommended: Use jsonToJava with USE_MAPS:true- Parameters:
json
- String of JSON contentoptionalArgs
- Map of optional arguments to control customization. See readme file for details on these options.maxDepth
- Maximum parsing depth.- Returns:
- Map where each Map representa an object in the JSON input.
-
jsonToMaps
public static Map jsonToMaps(String json, Map<String,Object> optionalArgs)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(String json, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null). No longer recommended: Use jsonToJava with USE_MAPS:true- Parameters:
json
- String of JSON contentoptionalArgs
- Map of optional arguments to control customization. See readme file for details on these options.- Returns:
- Map where each Map representa an object in the JSON input.
-
jsonToMaps
public static Map jsonToMaps(InputStream inputStream, Map<String,Object> optionalArgs, int maxDepth)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(inputStream, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null). No longer recommended: Use jsonToJava with USE_MAPS:true- Parameters:
inputStream
- containing JSON contentoptionalArgs
- Map of optional arguments to control customization. See readme file for details on these options.maxDepth
- Maximum parsing depth.- Returns:
- Map containing the content from the JSON input. Each Map represents an object from the input.
-
jsonToMaps
public static Map jsonToMaps(InputStream inputStream, Map<String,Object> optionalArgs)
Map args = ["USE_MAPS": true] Use JsonReader.jsonToJava(inputStream, args) Note that the return type will match the JSON type (array, object, string, long, boolean, or null). No longer recommended: Use jsonToJava with USE_MAPS:true- Parameters:
inputStream
- containing JSON contentoptionalArgs
- Map of optional arguments to control customization. See readme file for details on these options.- Returns:
- Map containing the content from the JSON input. Each Map represents an object from the input.
-
getObjectsRead
public Map<Long,JsonObject> getObjectsRead()
-
getRefTarget
public Object getRefTarget(JsonObject jObj)
-
readObject
public Object readObject()
Read JSON input from the stream that was set up in the constructor, turning it into Java Maps (JsonObject's). Then, if requested, the JsonObjects can be converted into Java instances.- Returns:
- Java Object graph constructed from InputStream supplying JSON serialized content.
-
jsonObjectsToJava
public Object jsonObjectsToJava(JsonObject root)
Convert a root JsonObject that represents parsed JSON, into an actual Java object.- Parameters:
root
- JsonObject instance that was the root object from the JSON input that was parsed in an earlier call to JsonReader.- Returns:
- a typed Java instance that was serialized into JSON.
-
useMaps
protected boolean useMaps()
-
convertParsedMapsToJava
protected Object convertParsedMapsToJava(JsonObject root)
This method converts a root Map, (which contains nested Maps and so forth representing a Java Object graph), to a Java object instance. The root map came from using the JsonReader to parse a JSON graph (using the API that puts the graph into Maps, not the typed representation).- Parameters:
root
- JsonObject instance that was the root object from the JSON input that was parsed in an earlier call to JsonReader.- Returns:
- a typed Java instance that was serialized into JSON.
-
newInstance
public static Object newInstance(Class c, JsonObject jsonObject)
-
close
public void close()
- Specified by:
close
in interfaceAutoCloseable
- Specified by:
close
in interfaceCloseable
-
-