繁体   English   中英

如何仅使用Gson存储非默认值

[英]How to only store non-default values with Gson

我制作了一个小型序列化系统,该系统使用Gson且仅影响具有特定Annotation Fields

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Store  {
    String valueName() default "";
    boolean throwIfDefault() default false;
}

throwIfDefault()确定如果Field的值等于默认值,是否应该将Field保存到文件中(我通过将字段的值与相同字段但在类的静态实例中进行比较来进行检查)。

它完美地工作,但是我想达到的目标是,对MapArraySet对象也是如此:

如果这些objects的条目未包含在该特定Field的默认实例中,则仅应保存它们。

它还必须为反序列化工作:

应该在反序列化过程中添加尚未包含在已加载object的默认值,或者首先加载默认object ,然后使用已加载object的条目进行修改。

通过为这些obejcts创建自定义Json(De)Serializer ,这是否可能?或者您将如何做?

这是反序列化部分:

public void Load() throws FileNotFoundException {
    Type typeOfHashMap = new TypeToken<LinkedHashMap<String, Object>>(){}.getType();
    FileReader reader = new FileReader(file);
    HashMap<String, Object> loadedMap = mainGson.fromJson(reader,typeOfHashMap);
    for(Field f: this.getClass().getDeclaredFields()) {
        if (!f.isAnnotationPresent(Store.class)) {
            continue;
        }
        try {
            f.setAccessible(true);
            Store annotation = f.getAnnotation(Store.class);
            Object defaultValue = DefaultRegistrator.getDefault(this.getClass(),f);
            if (!loadedMap.containsKey(annotation.valueName())) {
                f.set(this, defaultValue);
                continue;
            }
            Object loadedValue = mainGson.fromJson(
                loadedMap.get(annotation.valueName()).toString(), f.getType()
            );
            f.set(this, loadedValue);
        } catch(IllegalAccessException e) {

        } 
    }
}

假设您的JSON对象是

{"defParam1": 999,
 "defParam2": 999,
 "defParam3": 999,
 "param4": 999,
 "param5": 999,
 "param6": 999}

不会设置参数defParam1,defParam2,defParam3。

使用默认参数将JSON对象解析为特定对象

默认参数是在构造函数中设置的,因此您无需使用注释

您的Java对象是:

public class ObjStore {
    public ObjStore(){
        this(false);
    }
    // Load default parameters directly into the constructor
    public ObjStore(boolean loadDefault){
        if( loadDefault ){
            defParam1 = 123; // (int) DefaultRegistrator.getDefault("ObjStore", "defParam1");
            defParam2 = 123; // (int) DefaultRegistrator.getDefault("ObjStore", "defParam2");
            defParam3 = 123; // (int) DefaultRegistrator.getDefault("ObjStore", "defParam3");
        }
    }
    public int getDefParam1() {
        return defParam1;
    }

    public int getDefParam2() {
        return defParam2;
    }

    public int getDefParam3() {
        return defParam3;
    }

    public int getParam4() {
        return param4;
    }

    public void setParam4(int param4) {
        this.param4 = param4;
    }

    public int getParam5() {
        return param5;
    }

    public void setParam5(int param5) {
        this.param5 = param5;
    }

    public int getParam6() {
        return param6;
    }

    public void setParam6(int param6) {
        this.param6 = param6;
    }

    private int defParam1;
    private int defParam2;
    private int defParam3;
    private int param4;
    private int param5;
    private int param6;
}

对于反序列化,您需要以这种方式注册新的自定义typeAdapter:

GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(ObjStore.class, new JsonDeserializer<ObjStore>() {
    public ObjStore deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        ObjStore objStore = new ObjStore(true);
        JsonObject jo = json.getAsJsonObject();
        objStore.setParam4( jo.get("param4").getAsInt() );
        objStore.setParam5(jo.get("param5").getAsInt());
        objStore.setParam6(jo.get("param6").getAsInt());
        return objStore;
    }
});

Gson gson = gsonBuilder.create();

您可以使用以下方法解析JSON对象:

ObjStore objStore = gson.fromJson("{\"defParam1\": 999,\"defParam2\": 999,\"defParam3\": 999,\"param4\": 999,\"param5\": 999,\"param6\": 999}", ObjStore.class);

使用默认参数将JSON对象解析为Map对象

默认参数是在构造函数中设置的,因此您无需使用注释。

定义包装您的Map对象的此类

public class ObjMapStore {
    public ObjMapStore(){
        this(true);
    }
    public ObjMapStore(boolean loadDefault){
        map = new HashMap<>();
        if(loadDefault){
            map.put("defParam1", 123); // (int) DefaultRegistrator.getDefault("ObjMapStore", "defParam1");
            map.put("defParam2", 123); // (int) DefaultRegistrator.getDefault("ObjMapStore", "defParam2");
            map.put("defParam3", 123); // (int) DefaultRegistrator.getDefault("ObjMapStore", "defParam3");
        }
    }

    public void put(String key, Object value){
        map.put(key, value);
    }

    public Map<String, Object> getMap(){
        return map;
    }
    private Map<String, Object> map;
}

再次进行反序列化,您需要以这种方式注册新的自定义typeAdapter:

GsonBuilder gsonBuilder = new GsonBuilder();

gsonBuilder.registerTypeAdapter(ObjMapStore.class, new JsonDeserializer<ObjMapStore>() {
    public ObjMapStore deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        ObjMapStore objMapStore = new ObjMapStore();
        JsonObject jo = json.getAsJsonObject();
        objMapStore.put("param4", jo.get("param4").getAsInt());
        objMapStore.put("param5", jo.get("param5").getAsInt());
        objMapStore.put("param6", jo.get("param6").getAsInt());
        return objMapStore;
    }
});

Gson gson = gsonBuilder.create();

在使用以下方法获取地图对象之前,请完成以下操作:

Map<String, Object> objMapStore = gson.fromJson("{\"defParam1\": 999,\"defParam2\": 999,\"defParam3\": 999,\"param4\": 999,\"param5\": 999,\"param6\": 999}", ObjMapStore.class).getMap();

对此调用.getMap(); 因为允许您将Map定义到ObjMapStore返回的对象中

很高兴为您提供帮助,为任何问题写评论。 请记住投票并检查是否有帮助。 Byee

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM