美文网首页
ObjectBox Entity 与 Json 之间的相互转换/

ObjectBox Entity 与 Json 之间的相互转换/

作者: 楼若生 | 来源:发表于2018-06-26 15:48 被阅读0次

都知道在ObjectBox中,表关系在POJO中是用ToOneToMany对象来表示的。而当我们的业务场景中需要用到Json数据进行转换时,这两个对象的存在则成为了一种麻烦。那么我们该怎么处理这两个对象在Json数据序列化和反序列化的问题呢?

这里以Gson为例(基础配置过程省略)
Entity.class

class Entity {
  private String name;
  private String value;
 }

public void toJson(){
    String json=new Json().toJson(new Entity());
}
public void fromJson(){
    Entity entity=new Json().fromJson(json,Entity.class);
}

以上为Gson最简单基础的应用。
但是当我们的POJO涉及到ObejctBox的关联关系时,以上代码就不能解决问题了。

以下为建立了标间关系的Entity.classTarget.class,省略了IdObjectBox注解等。

class Entity {
  private String name;
  private String value;
  private List<Target> targets;//ToMany
//省略geter setter
 }

class Target {
  private String name;
  private String value;
  private ToOne<Entity> entity;
//省略geter setter
 }

ObjectBox中,ToMany本身实现了List接口,故在定义POJO时,可以将ToMany字段定义为List类型来使用该对象。

当我们创建EntityTarget的实例时,ObjectBox会自动为这里的List<Target> targets以及ToOne<Entity> entity属性分别实例化一个ToManyToOne对象,故不需要我们手动实例化。

以上两个class在使用Gson序列化时,Entity能成功被序列化,而Target对象则由于包含ToOne类型的属性无法成功序列化。在反序列化时,EntityList<Target> targets会被实例化为一个ArrayList对象,在ObjectBox中是不会对该属性进行操作的,需要我们再次手动转换。而Target则仍然因为ToOne类型的属性无法被反序列化,这不是我们希望看到的。
此时GsonTypeAdapter.class这个类则可以解决以上问题,由于内容较多,我在这里就不再对其用法及原理进行描述了,想要了解的请参考 你真的会用Gson吗?Gson使用指南(四)

直接看代码

JsonBox.class
public abstract class JsonBox {
    abstract public void fromJson(JsonObject jo, JsonDeserializationContext context);

    protected <T> void filling(List<T> toMany, Class<T> type, JsonElement jsonElement, JsonDeserializationContext context) {
        if (toMany == null)
            return;
        toMany.clear();
        if (jsonElement.isJsonArray()) {
            JsonArray array = jsonElement.getAsJsonArray();
            for (int i = 0; i < array.size(); i++) {
                JsonElement element = array.get(i);
                T item = context.deserialize(element, type);
                toMany.add(item);
            }
        }
    }

    protected <T extends JsonBox> void filling(ToOne<T> toOne, Type typeOfT, JsonElement jsonElement, JsonDeserializationContext context) {
        if (toOne == null)
            return;
        try {
            T one = ((Class<T>) typeOfT).newInstance();
            one.fromJson(jsonElement.getAsJsonObject(), context);
            toOne.setTarget(one);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}
继承并实现JsonBox.class

在有ToManyToOne类型属性的POPO中调用filling()方法为其填充数据

class Entity extends JsonBox {
  private String name;
  private String value;
  private List<Target> targets;//ToMany
@Override
    public void fromJson(JsonObject jo, JsonDeserializationContext context) {
        filling(targets, Target.class, jo.get("targets"), context);
    }
//省略geter setter
 }

class Target extends JsonBox {
  private String name;
  private String value;
  private ToOne<Entity> entity;
@Override
  public void fromJson(JsonObject jo, JsonDeserializationContext context) {
       filling(entity, Entity.class, jo.get("entity"), context);
  }
//省略geter setter
 }
ToOneSerializer.class 用于序列化时处理ToOne对象

由于ToMany不会对序列化产生任何影响,我们只需要处理遇到ToOne的情况,如下:

public class ToOneSerializer implements JsonSerializer<ToOne> {

    @Override
    public JsonElement serialize(ToOne src, Type typeOfSrc, JsonSerializationContext context) {
        return context.serialize(src.getTarget());
    }
}
JsonBoxDeserializer.class 用于反序列化时处理ToManyToOne对象
public class JsonBoxDeserializer<T extends JsonBox> implements JsonDeserializer<T> {
    @Override
    public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        try {
            T var = ((Class<T>) typeOfT).newInstance();
            var.fromJson(json.getAsJsonObject(), context);
            return var;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (Throwable e) {
            e.printStackTrace();
        }

        return null;
    }
}

最终通过将两个TypeAdapter注册到Gsonbuild一个Gson实例并调用

Gson gson=new GsonBuilder()
                .registerTypeHierarchyAdapter(JsonBox.class, new JsonBoxDeserializer<>())
                .registerTypeAdapter(ToOne.class, new ToOneSerializer())
                .create();
public void toJson(){
    String json=gson.toJson(new Entity());
}
public void fromJson(){
    Entity entity=gson.fromJson(json,Entity.class);
}

搞定!

相关文章

网友评论

      本文标题:ObjectBox Entity 与 Json 之间的相互转换/

      本文链接:https://www.haomeiwen.com/subject/lqxmyftx.html