org.kopitubruk.util.json
Class JSONUtil

java.lang.Object
  extended by org.kopitubruk.util.json.JSONUtil

public class JSONUtil
extends Object

This class converts certain common types of objects into JSON using the static methods toJSON(Object), toJSON(Object,JSONConfig), toJSON(Object,Writer) and toJSON(Object,JSONConfig,Writer). Collections are traversed and encoded, allowing complex data graphs to be encoded in one call. It's more flexible than the org.json library and in many cases may allow the use of existing data structures directly without modification which should reduce both memory and CPU usage.

There are a number of configuration options available by passing a JSONConfig object to the toJSON methods. In most cases, the defaults are adequate so you don't need to pass a JSONConfig object if you don't want to. You can also change the defaults for some of the options so that you don't have to pass the object even if you want non-default behavior. Keep in mind that doing that affects all new JSONConfig objects that are created after that in the same class loader.

This implementation validates property names by default using the specification from ECMAScript and ECMA JSON standards. The validation can be disabled for faster performance. See JSONConfig. Leaving it on during development and testing is probably advisable. Note that the ECMAScript standard for identifiers is more strict than the JSON standard for identifiers. If you need full JSON identifiers, then you should enable fullJSONIdentifierCodePoints in your JSONConfig. Keep in mind that JSON generated that way may not evaluate properly in Javascript eval().

There is some effort to detect loops in the data structure that would cause infinite recursion and throw an exception. This detection is not perfect and there are some ways to fool it, so try to be careful and not make loops in your data structures.

Top level objects which can be sent to the toJSON methods:

Maps
In most cases, this will be what you will send to the toJSON method. The Map becomes a Javascript object with the property names being the result of the key's toString() method and the values being property values. The key's toString() must produce valid Javascript/JSON identifiers and the values can be almost anything. Note that this is different than the org.json library which requires the keys to actually be Strings. If your key's toString() method does not produce valid Javascript/JSON identifiers then you can use JSONConfig.setEscapeBadIdentifierCodePoints(boolean) to make it so that they are valid identifiers.
ResourceBundle
Converted to a Javascript object with the keys being the property names and the values being from ResourceBundle.getObject(String).
Iterables, Enumerations and arrays
These are encoded as Javascript arrays. These can also be top level if you want an array as your top level structure. Note that Collection is a sub-interface of Iterable, so all collections are covered by this.
JSONAbles
These are objects that know how to convert themselves to JSON. This just calls their JSONAble.toJSON(JSONConfig,Writer) method. It is possible to use these as top level objects or as values inside other objects but it's kind of redundant to use them as top level. A class called JsonObject is included with this package that implements JSONAble and provides a few conveniences for creating JSON object data.
Reflected Objects
Any object that has been added to the JSONConfig as an object to use reflection for encoding. See JSONConfig.addReflectClass(Object) and JSONConfig.addReflectClasses(Collection). If JSONConfig.isReflectUnknownObjects() returns true, then any unrecognized object will become a reflected object.

Other objects which can commonly be values in Maps, Iterables, Enumerations, arrays and reflected objects.

Numbers
Anything that implements the Number interface, which is all of the wrapper objects for primitive numbers and BigInteger and BigDecimal. They normally have their toString() methods called. Primitive versions of these are also allowed in arrays and will be converted to their wrapper objects. These get whatever their object's toString() method gives. It is possible to set number formats for any number type in the JSONConfig. If those are set then they will be used instead of toString().
Booleans
Encoded as boolean literals.
Dates
If JSONConfig.isEncodeDatesAsStrings() returns true, then Dates will be encoded as ISO 8601 date strings, suitable for handing to new Date(String) in Javascript. The date format can be changed to something else by JSONConfig.setDateGenFormat(java.text.DateFormat).

If JSONConfig.isEncodeDatesAsObjects() returns true, then Dates will be encoded as a call to the Date constructor in Javascript using an ISO 8601 date string. This works with Javascript eval(). It probably won't work in most strict JSON parsers. The date format can be changed to something else by JSONConfig.setDateGenFormat(java.text.DateFormat).

CharSequences
CharSequences such as String and StringBuilder are encoded as Javascript strings with escapes used as needed according to the ECMA JSON standard and escape options from JSONConfig.
Any other object
If reflection is disabled (which it is by default), then any other object just gets its toString() method called and it's encoded like any other String.

If reflection is enabled for the specific type or for all unknown types then The package will attempt to figure out how to encode the fields of the given object according to the privacy level set by JSONConfig.setReflectionPrivacy(int) using JavaBeans compliant getters if available or accessing fields directly if not. See JSONConfig.addReflectClass(Object), JSONConfig.addReflectClasses(Collection) and JSONConfig.setReflectUnknownObjects(boolean) for ways to enable reflection. These methods are also available in JSONConfigDefaults if you want to make them the default behavior.

null
Encoded as the Javascript literal null.

Author:
Bill Davidson
See Also:
JSONAble, JSONConfig, JSONConfigDefaults

Method Summary
static void checkValidJavascriptPropertyName(String propertyName)
          Checks if the input string represents a valid Javascript property name using default identifier options.
static void checkValidJavascriptPropertyName(String propertyName, JSONConfig cfg)
          Checks if the input string represents a valid Javascript property name.
static Set<String> getJavascriptReservedWords()
          Get the list of reserved words.
static boolean isReservedWord(String name)
          Check if the given string is a reserved word.
static boolean isValidJavascriptPropertyName(String propertyName)
          Return true if the input string is a valid Javascript property name using default identifier options.
static boolean isValidJavascriptPropertyName(String propertyName, JSONConfig cfg)
          Return true if the input string is a valid Javascript property name.
static String toJSON(Object obj)
          Convert an object to JSON and return it as a String.
static String toJSON(Object obj, JSONConfig cfg)
          Convert an object to JSON and return it as a String.
static void toJSON(Object obj, JSONConfig cfg, Writer json)
          Convert an object to JSON and write it to the given Writer.
static void toJSON(Object obj, Writer json)
          Convert an object to JSON and write it to the given Writer.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

toJSON

public static String toJSON(Object obj)
Convert an object to JSON and return it as a String. All options will use defaults.

Parameters:
obj - An object to be converted to JSON.
Returns:
A JSON string representation of the object.

toJSON

public static String toJSON(Object obj,
                            JSONConfig cfg)
Convert an object to JSON and return it as a String.

Parameters:
obj - An object to be converted to JSON.
cfg - A configuration object to use.
Returns:
A JSON string representation of the object.

toJSON

public static void toJSON(Object obj,
                          Writer json)
                   throws IOException
Convert an object to JSON and write it to the given Writer. All options will be default. Using a Writer may be preferable in servlets, particularly if the data is large because it can use a lot less memory than a StringBuffer by sending the data to the browser via a BufferedWriter on the output stream as it is being generated. The downside of that is that you could have an error after data begins being sent, which could result in corrupted partial data being sent to the caller.

Parameters:
obj - An object to be converted to JSON.
json - Something to write the JSON data to.
Throws:
IOException - If there is an error on output.

toJSON

public static void toJSON(Object obj,
                          JSONConfig cfg,
                          Writer json)
                   throws IOException
Convert an object to JSON and write it to the given Writer. Using a Writer may be preferable in servlets, particularly if the data is large because it can use a lot less memory than a StringWriter by sending the data to the browser via a BufferedWriter on the output stream as it is being generated. The downside of that is that you could have an error after data begins being sent, which could result in corrupted partial data being sent to the caller.

Parameters:
obj - An object to be converted to JSON.
cfg - A configuration object to use to set various options. If null then defaults will be used.
json - Something to write the JSON data to.
Throws:
IOException - If there is an error on output.

getJavascriptReservedWords

public static Set<String> getJavascriptReservedWords()
Get the list of reserved words.

Returns:
the set of reserved words.

isReservedWord

public static boolean isReservedWord(String name)
Check if the given string is a reserved word.

Parameters:
name - The name to check.
Returns:
true if the name is a reserved word.

checkValidJavascriptPropertyName

public static void checkValidJavascriptPropertyName(String propertyName,
                                                    JSONConfig cfg)
                                             throws BadPropertyNameException
Checks if the input string represents a valid Javascript property name.

Parameters:
propertyName - A Javascript property name to check.
cfg - A JSONConfig to use for locale and identifier options. If null, defaults will be used.
Throws:
BadPropertyNameException - If the propertyName is not a valid Javascript property name.

checkValidJavascriptPropertyName

public static void checkValidJavascriptPropertyName(String propertyName)
                                             throws BadPropertyNameException
Checks if the input string represents a valid Javascript property name using default identifier options.

Parameters:
propertyName - A Javascript property name to check.
Throws:
BadPropertyNameException - If the propertyName is not a valid Javascript property name.

isValidJavascriptPropertyName

public static boolean isValidJavascriptPropertyName(String propertyName,
                                                    JSONConfig cfg)
Return true if the input string is a valid Javascript property name.

Parameters:
propertyName - A Javascript property name to check.
cfg - A JSONConfig to use for locale and identifier options. If null, defaults will be used.
Returns:
true if the input string represents a valid Javascript property name.

isValidJavascriptPropertyName

public static boolean isValidJavascriptPropertyName(String propertyName)
Return true if the input string is a valid Javascript property name using default identifier options.

Parameters:
propertyName - A Javascript property name to check.
Returns:
true if the input string represents a valid Javascript property name.


Copyright © 2016. All rights reserved.