How do I correctly deserialize .NET Dictionaries using Jackson?

五迷三道 提交于 2019-12-11 19:04:22

问题


to sum it up before the wall of text below :-)

I need help with how to deserialize a Dictionary using Jackson and a custom deserializer.

Right now I have an Android app communication with a .NET (C#) server. They use JSON to communicate.

On the JAVA-side, I am using Jackson to handle the JSON and on the .NET-side I am using the built in DataContractSerializer (I know, ppl will start commenting I should use something else, but Im not so... ;-) )

The problem is that I am sending Dictionaries from C# and I want that to be deserialized to HashMaps om the JAVA-side, but I havent found a good resource for how to do that.

One example of a Dictionary I am sending from C#:

// Here, the object Equipment is the key, and the int following indicates the amount
[DataMember]
public Dictionary<Equipment, int> EquipmentList { get; set; }

And just for reference, the Equipment object in C#:

[DataContract]
public class Equipment
{
    [DataMember]
    public uint Id { get; set; }
    [DataMember]
    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        if (obj.GetType() != this.GetType())
            return false;
        Equipment e = (Equipment)obj;
        return e.Id == this.Id;
    }
}

Its serialized correctly into decent JSON on the C#-side, the Dictionary looks like this:

//....
"EquipmentList":[
   {
      "Key":{
         "EquipmentId":123,
         "Name":"MyName"
       },
       "Value":1
   }
//....

I have added a custom serializer (CustomMapSerializer), like this:

public static ObjectMapper mapper = new ObjectMapper();
private static SimpleDeserializers simpleDeserializers = new SimpleDeserializers();
private static StdDeserializerProvider sp = new StdDeserializerProvider();

public static void InitSerialization()
{
    simpleDeserializers.addDeserializer(String.class, new CustomStringDeserializer());
    simpleDeserializers.addDeserializer(Map.class, new CustomMapDeserializer());
    sp.withAdditionalDeserializers(simpleDeserializers);
    mapper.setDeserializerProvider(sp);
}

And decorated the field like this:

@JsonDeserialize(using=CustomMapDeserializer.class)
public Map<Equipment, Integer> EquipmentList;

And finally, when I run it I do get a break in the custom deserializer class, but I am not sure how to proceed from here:

public class CustomMapDeserializer extends JsonDeserializer<Map> {

    @Override
    public Map deserialize(JsonParser arg0, DeserializationContext arg1) throws IOException, JsonProcessingException 
    {
        return new HashMap<Object, Object>(); // <-- I can break here
    }   
}

So, what I would like is some input on how to create a HashMap with the correct values in it, ie a deserialized Equipment as Key and an Int as value.

Anyone out there who can assist? =)


回答1:


Ok, after a while testing and researching, this is what I came up with.

The custom deserializer looks like this:

    public class CustomMapCoTravellerDeserializer extends JsonDeserializer<Map> {

    @Override
    public Map deserialize(JsonParser jp, DeserializationContext arg1) throws IOException, JsonProcessingException 
    {
        HashMap<CoTravellers, Integer> myMap = new HashMap<CoTravellers, Integer>();

            CoTravellers ct = new CoTravellers();

            jp.nextToken(); // {
            jp.nextToken(); // Key
            jp.nextToken(); // {
            jp.nextToken(); // "CoTravellerId"
            jp.nextToken(); // CoTravellerId Id
            int coTravellerValue = jp.getIntValue();
            jp.nextToken(); // Name
            jp.nextToken(); // Name Value
            String coTravellerName = jp.getText();
            jp.nextToken(); // }
            jp.nextToken(); // "Value"
            jp.nextToken(); // The value
            int nbr = jp.getIntValue();



            ct.CoTravellerId = coTravellerValue;
            ct.Name = coTravellerName;

            myMap.put(ct, nbr);


            return myMap;

    }   
}

I think this will work, if I can only figure out the JsonMappingException I am getting... but I will post on that separately =)



来源:https://stackoverflow.com/questions/14543119/how-do-i-correctly-deserialize-net-dictionaries-using-jackson

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!