0

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.

Community
  • 1
  • 1
Goltsev Eugene
  • 3,325
  • 6
  • 25
  • 48

3 Answers3

1

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.

Community
  • 1
  • 1
arjabbar
  • 6,044
  • 4
  • 30
  • 46
  • Yeah, I suppose custom Deserializer would be the only option. Main problem that Info is a String - if it would be nested JSON, that's would be easy. – Goltsev Eugene Jun 10 '16 at 06:41
0

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 
}
sudar
  • 1,446
  • 2
  • 14
  • 26
  • It's not working, as Info is a String: `com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 46` – Goltsev Eugene Jun 10 '16 at 06:33
0

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.

omkarmoghe
  • 76
  • 1
  • 6
  • Thanks, but it's not working - reason is the same - Info is a String: `com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 46` – Goltsev Eugene Jun 10 '16 at 06:38
  • @GoltsevEugene Ah, I see. I did not notice that the entire field was encapsulated in quotes. In that case, you will have to use a custom deserializer as arjabbar mentioned above – omkarmoghe Jun 10 '16 at 14:28