"org.json.JSONArray implements Serializable": What's the best option to achieve this?

arrays, grails, java, json, serialization

Solution

Wrap it as a `transient` property in a class which implements `Serializable` and has the `readObject()` and `writeObject()` overridden.

public class SerializableJSONArray implements Serializable {
    private transient JSONArray jsonArray;

    public SerializableJSONArray(JSONArray jsonArray) {
        this.jsonArray = jsonArray;
    }

    public JSONArray getJSONArray() {
        return jsonArray;
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();
        oos.writeObject(jsonArray.toString());
    }

    private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException, JSONException {
        ois.defaultReadObject();
        jsonArray = new JSONArray((String) ois.readObject());
    }
}

You see that there's a getter which returns the wrapped JSONArray. Use it in your domain objects instead. Optionally you can also let this class `extends JSONArray` and delegate all of its methods to the wrapped JSONArray. A decent IDE can autogenerate them for you in a second.

Problem

I am using Grails Webflow, what ever object I pass to a view, it must be Serialized. My domain models "implement Serializable", so they work. The problem is when I get a response from a WebService. It is of the org.json.JSONArray class. I just want to pass the whole Array over to the view yet it doesn't implement Serializable, so it fails, Any thoughts on how I can pass this, or my best option? Can I just edit the source of the org.json library and make every class "imp Serializable"? Or process the result into Domain objects that do "imp Serializable"

Original source