Goltsev Eugene
Goltsev Eugene

Reputation: 3627

GSON if deserialized string contains another JSON

Not so typical situation.

I have next JSON string from server:
{"SomeElements":[{"Id":"Title","Info":"{\"Text\": \"Sometext\"}"}]}

Here is graphic representation of it:

enter image description here

The problem is that string Info contains another JSON string.
Here is my POJO:

public class Test {
    private ArrayList<SomeElement> SomeElements;

    public class SomeElement {
        private String Id;
        private String Info;
    }
}

Question - is there some way to parse Info string not as String, but as HashMap (for example) in my POJO?

If I try to declare it as HashMap<String, String>, I have an error "Expected OBJECT, but was STRING".

What is the best approach to handle this issue? Custom deserializer is the only way?


!! This question is NOT a duplicate !!
I cannot change JSON response from the server.
Please read carefully - I'm asking, is it possible to parse Info string not as string, but as another JSON.

SOLUTION I ended up with next.
I declared private LinkedTreeMap<String, String> infoMap; and Firstly deserialize Info as String. Then:

public LinkedTreeMap<String, String> getInfoMap() {
            if (infoMap == null) {
                infoMap = new Gson().fromJson(info, new TypeToken<Map<String, String>>(){}.getType());
            }
            return infoMap;
        }

I suppose this is much easier than writing custom deserializer, but maybe in more complex cases custom deserializer would be an only option.
So in general case answer of @arjabbar would work better.

Upvotes: 0

Views: 324

Answers (3)

omkarmoghe
omkarmoghe

Reputation: 76

You need to create a class for the Info object as well so that GSON will deserialize it for you.

Try this:

public class EntireJsonObject {
    private ArrayList<SomeElement> someElements;
}

public class SomeElement {
    private String id;
    private Info info;
}

public class Info {
    private String text;
}

You need to have GSON deserialize the JSON response from the server to a EntireJsonObject. GSON will handle all the inner conversions and deserializations for you. Now you can access the "SomeText" as through a getter from the Info object.

It is important to note that your variable names do not have to exactly match the keys returned in the JSON response. GSON will translate variable names based on various schemes (camelCase, under_scores, and many more). You can specify the conversion protocal GSON uses when you create the object.

If you absolutely want the Info as a HashMap<String, String>, you will have to write the deserializer for that individually. I would check the GSON docs, as you may not have to write a custom deserializer for the entire JSON response, but rather just the inner object.

Upvotes: 0

nps
nps

Reputation: 384

Here Info is also object. so you need to create the class for info.

public class Test {
    private ArrayList<SomeElement> SomeElements;

    public class SomeElement {
        private String Id;
        private Info info;
    }

}
class Info{
private String text;
private String sometext;
//getter and setter 
}

Upvotes: 0

arjabbar
arjabbar

Reputation: 6404

You have a couple of options, but I think your best bet is to just make a custom Deserializer. It's not your only way, but once you get used to writing Deserializers, it's not so bad.

Here are some decent examples.

Upvotes: 1

Related Questions