JSONObject 不可序列化?

Posted

技术标签:

【中文标题】JSONObject 不可序列化?【英文标题】:JSONObject Not Serializable? 【发布时间】:2011-08-20 13:35:30 【问题描述】:

我正在尝试序列化 JSONObjects 的 ArrayList。但我得到了错误:

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)

这是我的序列化和反序列化代码:

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】:

老兄,这是 JSON。为什么不直接将其序列化为 JSON,而不是 JSONObject 类型的 Java 对象?

例如:

String myJsonObjectSerialized = myJsonObject.toString();

【讨论】:

您能详细说明一下吗?也许我只是完全错过了它——也许是一个小代码示例? 酷。我存储的结构是 JSONObjects 的 ArrayList。我该怎么做呢? @Sheehan Alam - 要么将 JSONObjects 放入 JSONArray,要么使用 for 循环。 另一种情况是带有 JSONObject 的 HashMap,如以下问题所示:***.com/questions/3818745/…(将 Bottle 替换为 JSONObject 刚刚偶然发现了这个问题。不在用于序列化的类上实现 Serializable 是……至少可以说是一个有趣的决定。它根本不会破坏任何东西,还是我在这里遗漏了什么?【参考方案2】:

如果您仍然希望 Java 内置序列化而不必将 JSON 对象编组为字符串表示法,您可以做的一件事是从 org.json 扩展 JSONObject 和 JSONArray 并实现 Serializable。

然后,您可以全面使用自己的 JSONObject 和 JSONArray 版本,而不是原来的版本。

确保在子类上定义所有构造函数并调用它们的 super() 对应项,并实现从属性返回父类型的特定方法,例如 getJSONObject() 和 getJSONArray()。

【讨论】:

投票,因为这是正确的方法。我也是这样做的,因为我在 MemCache 上缓存了一个复杂的 JSONObject,而不是一直创建它或将其字符串化。 这似乎可行,但这样做“安全”吗?扩展一个不可序列化的 3rd 方类,然后将其标记为可序列化,这似乎有点冒险。 这是一种比公认的方法更好的方法!【参考方案3】:

如果您在 Serializable 对象类中有 JSONArray,请尝试以这种方式初始化 JSONArray。

私有瞬态 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;  
       

 

【讨论】:

因为它会改变功能,你可能不想在反序列化时丢失你的 JSONArray..【参考方案4】:

另一种方法是将org.json 库与json-simple 交换。

json-simple 中的 JSONObject 类扩展了 HashMap,它是 java Serializable 以及更多 java-ish API。

Maven 依赖:

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

示例用法:

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

【讨论】:

以上是关于JSONObject 不可序列化?的主要内容,如果未能解决你的问题,请参考以下文章

net.sf.json.JSONObject 和org.json.JSONObject 的差别

Json数据转Map

java怎么读取json格式的数据

JSON解析

JSON的put方法是一个指针引用

IEnumerable 在 Json.NET 中序列化为 [JsonObject],不使用属性