JSONObject не сериализуем?

Я пытаюсь сериализовать ArrayList JSONObjects. Но я получаю сообщение об ошибке:

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();
        }
    }

person Sheehan Alam    schedule 07.05.2011    source источник


Ответы (4)


Чувак, это JSON. Почему бы просто не сериализовать его как JSON, а не как объект Java типа JSONObject?

Например:

String myJsonObjectSerialized = myJsonObject.toString();

person Thane Anthem    schedule 07.05.2011
comment
Не могли бы вы уточнить? Может быть, я просто полностью упустил это - возможно, небольшой пример кода? - person Sheehan Alam; 07.05.2011
comment
Прохладный. Структура, которую я храню, представляет собой ArrayList JSONObjects. Как мне это сделать? - person Sheehan Alam; 07.05.2011
comment
@Sheehan Alam - либо поместите JSONObjects в JSONArray, либо используйте цикл for. - person Stephen C; 07.05.2011
comment
Другим сценарием может быть HashMap с JSONObject, как в этом вопросе: stackoverflow.com/questions/3818745/ (замените Bottle на JSONObject) - person nuala; 29.07.2013
comment
Только что наткнулся на эту проблему. Не реализовывать Serializable в классе, который используется для сериализации, это... интересное решение, если не сказать больше. Не то чтобы это вообще что-то сломало, или я что-то здесь упускаю? - person domenukk; 06.11.2016
comment
@ThaneAnthem Как я могу поместить и получить этот JSONObject внутри кеша в памяти, такого как Memcached? - person Jinu P C; 10.01.2018
comment
При использовании toString() объекты Date будут преобразованы в строку. Поэтому при преобразовании строки обратно в JSONObject она будет другой! - person Jan Gassen; 11.10.2018
comment
@TaneAnthem Что, если мой тип БД - jsonb? Он должен быть приведен к типу, чтобы сохраниться - person Varshney P.; 08.11.2019

В случае, если вам по-прежнему нужна встроенная сериализация Java без необходимости прибегать к маршалированию вашего объекта JSON в строковую нотацию, вы можете расширить JSONObject и JSONArray из org.json и просто реализовать Serializable.

Затем вы можете использовать свои собственные версии JSONObject и JSONArray по всем направлениям вместо оригиналов.

Убедитесь, что вы определили все конструкторы в своих подклассах и вызвали их аналоги super(), а также реализовали определенные методы, которые возвращают родительские типы, такие как getJSONObject() и getJSONArray() из свойств.

person Roberto Andrade    schedule 19.03.2013
comment
голосование вверх, так как это правильный подход. Я делаю то же самое, так как я кэширую составной JSONObject в MemCache, а не создаю его все время или преобразую в строку. - person gextra; 26.04.2013
comment
Кажется, это работает, но безопасно ли это делать? Кое-что о расширении стороннего класса, который не является сериализуемым, а затем пометить его как таковой, кажется немного рискованным. - person chinabuffet; 05.10.2016

Если у вас есть JSONArray внутри класса объектов Serializable, попробуйте инициализировать 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;  
     }  

 }
person mani    schedule 30.07.2015
comment
Поскольку это изменит функциональность, вы можете не захотеть потерять свой JSONArray при десериализации. - person James Andrew; 21.05.2017

Другой способ — поменять местами библиотеку org.json с json-simple.

Класс JSONObject из json-simple расширяет HashMap, который является java Serializable, а также более java-ish API.

Зависимость Мавена:

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/

person Thamme Gowda    schedule 14.03.2017