如何使用GSON反序列化自定义Map

时间:2016-04-15 09:25:39

标签: java serialization gson deserialization apache-commons-collection

我正在使用Apache Collection' this.Configuration.Users.RemoveAt(index); this.Configuration.Users.Insert(index, user); 提供BidiMap课程。我必须在项目中使用这个类。

使用它进行序列化没有问题。但是我在反序列化方面遇到了问题!

以下是一个示例类:

DualHashBidiMap

主要方法

package com.description;

import org.apache.commons.collections4.BidiMap;
import org.apache.commons.collections4.bidimap.DualHashBidiMap;

public class Sample {

    private String id;
    private String adress;

    BidiMap<Integer, String> items = new DualHashBidiMap<Integer, String>();


    public Sample() {
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getAdress() {
        return adress;
    }

    public void setAdress(String adress) {
        this.adress = adress;
    }

    public BidiMap<Integer, String> getItems() {
        return items;
    }

    public void setItems(BidiMap<Integer, String> items) {
        this.items = items;
    }
}

**

**

Sample sample = new Sample();
        sample.setId("12312xoa01");
        sample.setAdress("Houston, 43.1");
        BidiMap<Integer, String> items = new DualHashBidiMap<Integer, String>();
        items.put(1,  "gloves");
        items.put(90, "boots");
        sample.setItems(items);

        try {
            String result =  gson.toJson(sample);
            System.out.println("result : "+result);
            Sample sample2 = gson.fromJson(result, Sample.class);
            System.out.println("address : "+sample2.getAdress());

        }catch (Exception e){
            e.printStackTrace();
        }

2 个答案:

答案 0 :(得分:0)

为什么需要使用BidiMap?

检查这些:

deserializing generics with gson

How to deserialize a ConcurrentMap with Gson

尝试使用Map或LinkedHashMap或稍后从Map手动解析到BidiMap类型,以检查错误是否仍然存在。编写TypeAdapter也是一种选择。

顺便说一句:您的JSON不是Map<Integer,String>而是Map<String,String>地图{"1":"gloves","90":"boots"}

我之前尝试过GSON,它可以很好地与Java中的本机类型配合使用。我从未尝试过解析其他库,因为我认为你需要一个TypeAdapter。

答案 1 :(得分:0)

这不是那么简单,但可以做到:

public class BidiMapTypeAdapterFactory implements TypeAdapterFactory {

    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        if (!BidiMap.class.isAssignableFrom(type.getRawType())) {
            return null;
        }
        final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
        return new TypeAdapter<T>() {
            @Override
            public void write(JsonWriter out, T value) throws IOException {
                delegate.write(out, value);
            }

            @Override
            public T read(JsonReader in) throws IOException {
                return (T) new DualHashBidiMap<>((Map) delegate.read(in));
            }
        };
    }
}

注册TypeAdapterFactory:

GsonBuilder b = new GsonBuilder().registerTypeAdapterFactory(new BidiMapTypeAdapterFactory());
Gson gson = b.create();

现在你可以运行你的样本,它应该可以工作。