【问题标题】:How can I serialize a RealmObject to JSON in Realm for Java?如何在 Realm for Java 中将 RealmObject 序列化为 JSON?
【发布时间】:2015-03-10 06:33:38
【问题描述】:

我正在为我的应用程序实现一个数据库,我正在尝试将它“连接”到我的 REST 接口。数据以 JSON 形式出现,并且使用新的 JSON 支持(从 Realm 0.76 开始),我可以将 JSON 扔到我的Realm.createObjectFromJson(MyType.class, jsonString),它会创建适当的对象和 RealmList。

但是我该怎么做呢?也就是说,取一个 RealmObject 并将其序列化为 JSON?它还应该序列化该对象内的任何 RealmList。

【问题讨论】:

    标签: android json serialization realm


    【解决方案1】:

    来自Realm的Christian。 Realm for Android 目前没有任何这样的方法,虽然核心数据库实际上支持 JSON 序列化,所以现在你要么必须手动完成,要么使用像 GSON 这样的 3rd 方工具(警告,我没有测试过那个场景但是)。

    【讨论】:

    • 感谢您的回复。你能给我一个关于如何手动做到这一点的提示吗?我(浅浅地)试图通过覆盖 toString 方法来实现这一点。但它接缝我只能在我的 RealmObject-Classes 中拥有我的字段的设置器/获取器,除此之外没有其他方法。
    • 我可能会在接受您的模型类并输出 JSON 的一侧有一个 Util 类。您可以通过多种方式构造 JSON。手动或使用 JSONObject/JSONArray。
    • @ChristianMelchior 手动操作的步骤是什么?您需要将 RealmObject 转换回原始对象吗?
    • @ChristianMelchior - 我们什么时候可以看到这个功能?
    • 我们目前并未积极致力于原生 JSON 支持,但我们即将合并此 PR github.com/realm/realm-java/pull/1849。如果将其与 GSON 结合使用,则无需使用自定义 GSON 序列化程序即可转换回 JSON。
    【解决方案2】:

    以下是使用 GSON 库的方法。

    假设我们有以下来自服务器的 json 回复:

    {
       "data": [
          {
             "id": "1",
             "name": "John",
             "surname": "Doe"
          }
       ]
    }
    

    对于这个 Json 对象,我们创建一个具有相应属性的辅助类

        public class JsonHelperClass {
    
        String id;
        String name;
        String surname;
    
        public JsonHelperClass() {
        }
    
        public JsonHelperClass(String id, String name, String surname) {
            this.id = id;
            this.name = name;
            this.surname = surname;
        }
    
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getSurname() {
            return surname;
        }
        public void setSurname(String surname) {
            this.surname = surname;
        }
    }
    

    现在下面的 jsonReply 是包含来自服务器的回复的字符串

        JSONArray jsonArray = new HttpManager().getJsonArrayFromReply(jsonReply);
    
        if(jsonArray == null || jsonArray.length <0){
            return;
        }
    
        for (int i = 0; i < jsonArray.length(); i++) {
    
            JSONObject json = null;
            try {
            json = (JSONObject) array.get(i);
            } catch (JSONException e) {
            return null;
            }
    
            Gson gson = new Gson();
    
            JsonHelperClass helperClass = gson.fromJson(json.toString(), JsonHelperClass.class);
    
            createRealmObject(helperClass);
    
    }
    
    
        public void createRealmObject(JsonHelperClass helperClass){
    
            Realm realm = Realm.getInstance(context);
    
            realm.beginTransaction();
    
            RealmDataObject obj = realm.createObject(RealmDataObject.class);
    
            obj.setId(helperClass.getId());
            obj.setName(helperClass.getName());
            obj.setSurname(helperClass.getSurname());
    
            realm.commitTransaction();
    
    
    }
    
         public JSONArray getJsonArrayFromReply(String reply){
    
            JSONArray array = null;
    
            try {
                JSONObject jsonResp = new JSONObject(reply);
                array = jsonResp.getJSONArray("data");
    
            } catch (JSONException e) {
                return null;
            }
    
            return array;
        }
    

    还有领域数据对象

        public class RealmDataObject extends RealmObject {
    
        private String id;
        private String name;
        private String surname;
    
        public RealmDataObject() {
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getSurname() {
            return surname;
        }
    
        public void setSurname(String surname) {
            this.surname = surname;
        }
    
    
    }
    

    【讨论】:

    • 这实质上是处理过程的序列化部分,从 0.76 版开始由 Realm 处理。我想做相反的事情,即取一个对象并将其放入它的字符串表示中。现在,我只是编写自己的反序列化器,我很好。回答您的问题:从 Realm 0.77 版开始,您可以省略 HelperClass,因为您不再需要通过 Realm only 创建对象。您可以做一个简单的new RealmDataObject() 并填写数据,甚至更简单,让 Gson 完成工作(就像在您的示例中使用 HelperClass 所做的那样)
    • 我必须调查一下……RealmDataObject 线程安全吗?
    • AFAIK 是的,是的。因为对 RealmDataObject 的所有修改都必须在事务中进行,因此它们是原子的和线程安全的。
    • 嗨,我很想了解更多有关 RealmDataObject 的信息,但找不到任何东西,你知道任何文章吗?谢谢
    • 但是,更简单的是,不需要将 JSONArray 转换为 Gson,只需调用 JSONArray jsonArray = new HttpManager().getJsonArrayFromReply(jsonReply); realm.createAllFromJson(RealmDataObject.class, jsonArray);现在,更简单的是,只需将您的 jsonReply 扔到您的 realm realm.createAllFromJson(RealmDataObject.class, jsonReply);你不需要转换任何东西。只需将您从网络中获得的字符串扔到您的领域...
    【解决方案3】:

    将 JSON 反序列化为 RealmObject 使用以下各项

    假设你有这样的类定义

     @RealmClass
     public class Foo extends RealmObject{
      private String name;
      public void setName(String name){ this.name = name}
      public String getName(){ return this.name}
    } 
    

    还有一个像这样的 json 负载:

     String json = "{\"name\":\"bar\"}";
     Foo fooObject= realm.createObjectFromJson(Foo.class, json);
     //or 
     String jsonArray = "[{\"name\":\"bar\"},{\"name\":\"baz\"}]";
     RealmList<Foo> fooObjects = realm.createAllFromJson(Foo.class, jsonArray);
    

    但是,realm-core 本身并不支持反向操作。所以这就是我解决它的方法。我尝试使用 GSON,但最终编写了太多我自己不理解的代码,所以我实现了自己的适配器。问题是 RealmObjects 不是“领域”java.lang.Object

    创建一个适配器,它采用您的领域对象的实例并返回其 JSON 表示。

    示例。

     public class RealmJsonAdapter{
        public JSONObject toJson(Foo foo){
         JSONObject obj = new JSONObject();
         obj.putString("name",foo.getName());
         //if you have more fields you continue
         return obj;
         }
       }
    

    您现在可以在您的课程中使用此适配器将您的RealmObject 序列化为 JSON。最好让适配器成为一个接口,以便让调用者(可能是你自己)将想要使用的适配器传递给你。 然后你可以打电话说,adapter.toJSON(realmObjectInstance)。并获取您的 JSONObject 实现 毕竟你只关心 JSON 而不是 RealmObject。

    注意 这个解决方案有点过时了。 RealmObjects 现在是真正的 java 对象,因此您应该可以毫无问题地将它与 GSON 一起使用。只要确保您使用的是 0.89 或更高版本,一切都会正常运行。

    【讨论】:

      【解决方案4】:

      简单地说,你需要做的就是:

      Gson gson = //... obtain your Gson
      YourRealmObject realmObj = realm.where(YourRealmObject.class).findFirst();
      if(realmObj != null) {
          realmObj = realm.copyFromRealm(realmObj); //detach from Realm, copy values to fields
          String json = gson.toJson(realmObj);
      }
      

      【讨论】:

      • 这是 'realmObj = realmObj.copyFromRealm();'或'obj = realm.copyFromRealm(realmObj);' ??第二个对我有用。
      • @SakkeerHussain 抱歉,我一直认为 RealmObject 知道如何分离自己,但它是 realm.copyFromRealm(realmObject)。我相应地编辑了帖子。
      • 还没有测试过。如果realm对象里面有realm list,会不会也被翻译成json数组呢?
      • @ralphspoon 应该,考虑到默认的 copyFromRealm() 调用 takes a max depth parameterInteger.MAX_VALUE 的那个(如果您不想要列表,请使用 @ 987654326@ 参数与0)
      • @EpicPandaForce 这可能非常低效。建议创建自己的 gson TypeAdapter。
      【解决方案5】:

      试试这个

        private JSONArray convertRealmintoJSONArray(Activity context){
          try {
              RealmResults<ModelMyCart> results = RealmControllerMyCart.with(context).getBooks();
              JSONArray jsonArray = new JSONArray();
              for (ModelMyCart myCart : results
                      ) {
                  JSONObject object = new JSONObject();
                  object.put(Constants.PRODUCT_ID, myCart.getId());
                  object.put(Constants.PRODUCT_TITLE, myCart.getProduct_title());
                  object.put(Constants.PRODUCT_SIZE, myCart.getProduct_size());
                  object.put(Constants.PRODUCT_SELLINGFEE, myCart.getProduct_sellingfee());
                  object.put(Constants.PRODUCT_SELLINGFEE, myCart.getShipping_price());
                  object.put(Constants.PRODUCT_IMAGE, myCart.getProduct_image());
                  object.put(Constants.PRODUCT_BRAND, myCart.getProduct_brand());
                  object.put(Constants.PRODUCT_CATEGORY_ID, myCart.getProduct_category_id());
                  object.put(Constants.PRODUCT_CATEGORY_NAME, myCart.getProduct_category_name());
                  object.put(Constants.PRODUCT_COLOR, myCart.getProduct_color());
                  object.put(Constants.PRODUCT_COLORTYPE, myCart.getProduct_colortype());
                  object.put(Constants.PRODUCT_CONDITION, myCart.getProduct_condition());
                  object.put(Constants.PRODUCT_CREATED_DATE, myCart.getProduct_created_date());
                  object.put(Constants.PRODUCT_MYSALEPRICE, myCart.getProduct_mysaleprice());
                  object.put(Constants.PRODUCT_ORIGINALPRICE, myCart.getProduct_originalprice());
                  object.put(Constants.PRODUCT_POTENTIALEARNINGS, myCart.getProduct_potentialearnings());
                  object.put(Constants.PRODUCT_SHIPPINGCHARGES, myCart.getProduct_shippingcharges());
                  object.put(Constants.USER_ID, myCart.getUser_id());
                  object.put(Constants.USER_UNAME, myCart.getUser_uname());
                  jsonArray.put(object);
              }
              Log.e("Converted",""+jsonArray);
              return jsonArray;
          }catch (Exception e){
      
          }
          return null;
      }
      

      【讨论】:

        【解决方案6】:

        对于我的情况,new Gson().toJson(realm.copy(realmObj)); 导致 UI 冻结(有时内存不足异常)。所以我像这样更新了我的 Gson 实例

        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        
        String jsonString = gson.toJson(realm.copy(realmObj));
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多