-2

I've got a class that contains a HashMap in it and am struggling to deserialize it back into my class. Here's what the class looks like...

public class MyClass
{
    public String                   message;
    public String                   category;
    public HashMap<String,String>   customData = new HashMap<String, String>();
    public ArrayList<Device>        devices = new ArrayList<Device>();
}

If I don't register any kind of converter I get the following output...

{"MyClass": {
  "message": "My Message",
  "category": "My Category",
  "customData": [
    [
      "Name1",
      "Data1"
    ],
    [
      "Name2",
      "Data2"
    ],
    [
      "Name3",
      "Data3"
    ],
    [
      "Name4",
      "Data4"
    ]
  ],
  "devices": [
    {
      "id": 17,
      "firstName": "John",
      "lastName": "Smith",
      "devMode": false
    }
  ]
}}

This looks pretty good and what I am after. However when I try to then convert it back to MyClass I get a:

com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: Duplicate field customData

So its not liking the way my HashMap is encoded.

Therefore I've looked through various solutions to this and have tried the solution proposed here with this converter...

https://stackoverflow.com/a/44152959/1790578

and then register my converter...

theXStream.registerConverter (new XStreamMapConverter ());

The output I get when I encode to JSON is...

{"MyClass": {
  "message": "My Message",
  "category": "My Category",
  "customData": [
    "Data1",
    "Data2",
    "Data3",
    "Data4"
  ],
  "devices": [
    {
      "id": 17,
      "firstName": "John",
      "lastName": "Smith",
      "devMode": false
    }
  ]
}}

This obviously doesn't look right as it's dropping the first element of the HashMap (no Name's). This of course results in an exception when I try to convert it back from JSON to MyClass.

So I tried encoding it the first way above and then decoding it using the Converter. Still the same issue.

Any thoughts or insights here on how I could handle this?

UPDATE 1

Here's my new class with annotations...

public class MyClass
{
    public String                   message;
    public String                   category;

    @XStreamImplicit(itemFieldName="name")
    public HashMap<String,String>   customData = new HashMap<String, String>();

    public ArrayList<Device>        devices = new ArrayList<Device>();
}

This did not change my resulting JSON at all. I tried it with the NamedMapConverter and that too did not help. But I'm not sure if I have it setup properly?

NamedMapConverter namedMapConverter = new NamedMapConverter(theXStream.getMapper(),"customData","name",String.class,"value",String.class);
theXStream.registerConverter (namedMapConverter);
Etep
  • 533
  • 7
  • 20

1 Answers1

0

Ok even though this has already been marked down -2 I still feel it relevant to specify what the solution is here.

The problem is that I was mixing the JSON drivers. I'm a long time xstream user at least 8 years or more. There was a time where two different drivers were required for encoding and decoding the json. JsonHierarchicalStreamDriver and JettisonMappedXmlDriver. I can't remember the specific reason for this way back when but it appears the Jettison driver can be used both ways now. It may very well have always been the case but when it was explained to me I was supposed to use the JsonHierarchicalStreamDriver for encoding to json and the Jettison driver for decoding. Once I changed to the Jettison driver for both everything worked. The HashMap was properly encoded.

So the solution, don't mix the json drivers when creating your xstream. The JsonHierarchicalStreamDriver was the problem here.

Etep
  • 533
  • 7
  • 20