JSONObject Not Serializable?

2019-04-21 16:47发布

问题:

I am trying to serialize an ArrayList of JSONObjects. But I get the error:

05-07 01:04:24.130: WARN/System.err(913): java.io.NotSerializableException: org.json.JSONObject
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1535)
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-07 01:04:24.130: WARN/System.err(913):     at java.util.ArrayList.writeObject(ArrayList.java:651)
05-07 01:04:24.130: WARN/System.err(913):     at java.lang.reflect.Method.invokeNative(Native Method)
05-07 01:04:24.130: WARN/System.err(913):     at java.lang.reflect.Method.invoke(Method.java:507)
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1219)
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1575)
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1847)
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1689)
05-07 01:04:24.130: WARN/System.err(913):     at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1653)
05-07 01:04:24.130: WARN/System.err(913):     at org.stocktwits.activity.AddStocksActivity.serializeQuotes(AddStocksActivity.java:183)
05-07 01:04:24.130: WARN/System.err(913):     at org.stocktwits.activity.AddStocksActivity.access$9(AddStocksActivity.java:178)
05-07 01:04:24.130: WARN/System.err(913):     at org.stocktwits.activity.AddStocksActivity$2.onItemClick(AddStocksActivity.java:146)
05-07 01:04:24.130: WARN/System.err(913):     at android.widget.AdapterView.performItemClick(AdapterView.java:284)
05-07 01:04:24.130: WARN/System.err(913):     at android.widget.ListView.performItemClick(ListView.java:3513)
05-07 01:04:24.130: WARN/System.err(913):     at android.widget.AbsListView$PerformClick.run(AbsListView.java:1812)
05-07 01:04:24.130: WARN/System.err(913):     at android.os.Handler.handleCallback(Handler.java:587)
05-07 01:04:24.130: WARN/System.err(913):     at android.os.Handler.dispatchMessage(Handler.java:92)
05-07 01:04:24.130: WARN/System.err(913):     at android.os.Looper.loop(Looper.java:130)
05-07 01:04:24.130: WARN/System.err(913):     at android.app.ActivityThread.main(ActivityThread.java:3683)
05-07 01:04:24.130: WARN/System.err(913):     at java.lang.reflect.Method.invokeNative(Native Method)
05-07 01:04:24.130: WARN/System.err(913):     at java.lang.reflect.Method.invoke(Method.java:507)
05-07 01:04:24.130: WARN/System.err(913):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-07 01:04:24.130: WARN/System.err(913):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-07 01:04:24.130: WARN/System.err(913):     at dalvik.system.NativeStart.main(Native Method)

Here is my serialize & deserialize code:

private void serializeQuotes() {
        FileOutputStream fos;
        try {
            fos = openFileOutput(Constants.FILENAME, Context.MODE_PRIVATE);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(quotes);
            oos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unchecked")
    private void deserializeQuotes() {
        try {
            FileInputStream fis = openFileInput(Constants.FILENAME);
            ObjectInputStream ois = new ObjectInputStream(fis);
            quotes = (ArrayList<JSONObject>) ois.readObject();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

回答1:

Dude, it's JSON. Why not just serialize it as JSON, instead of as a Java object of type JSONObject?

For example:

String myJsonObjectSerialized = myJsonObject.toString();



回答2:

In the case you'd still want Java built-in serialization without having to resort to marshal your JSON object into string notation, one thing you could do is extend JSONObject and JSONArray from org.json and just implement Serializable.

Then you can use your own versions of JSONObject and JSONArray across the board instead of the originals.

Make sure you define all constructors on your subclasses and call their super() counterparts as well as implement specific methods that return the parent types such as getJSONObject() and getJSONArray() from properties.



回答3:

If you have JSONArray inside Serializable object class try to initialize JSONArray in this way.

private transient JSONArray jsonArray;

public class Person implements Serializable {   

     private String name;  
     private transient JSONArray jsonArray;

     public String getName() {  
          return name;  
     }  

    public void setName(String name) {  
          this.name = name;  
     }

    public JSONArray getJsonArray() {  
          return jsonArray;  
     }  

    public void setJsonArray(JSONArray jsonArray) {  
          this.jsonArray = jsonArray;  
     }  

 }


回答4:

Another way is to swap org.json library with json-simple.

The JSONObject class from json-simple extends HashMap which is java Serializable as well as more java-ish API.

Maven dependency:

http://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple/1.1.1

Example usage:

https://www.mkyong.com/java/json-simple-example-read-and-write-json/