0

I am trying to map below JSON to a POJO Class using Gson library. Below is the JSON response and POJO Class and mapping done

import java.util.Map;

import com.google.gson.JsonElement;

public class DataResponse {

    private String $status;
    private Map<String, JsonElement> $payload;

    public String get$status() {
        return $status;
    }

    public void set$status(String $status) {
        this.$status = $status;
    }

    public Map<String, JsonElement> get$payload() {
        return $payload;
    }

    public void set$payload(Map<String, JsonElement> $payload) {
        this.$payload = $payload;
    } 
}

Here is the Sample JSON.

{
  "$status": "OK",
  "$payload": {
    "$nextStart": "123",
    "$results": [
      {
        "$key": "101",
        "score": 3,
        "to": "Test1"
      },
      {
        "$key": "102",
        "score": 4,
        "to": "Test2"
      },
    ]
  }
}

Below is the mapping done. Is there some problem with POJO class definition. Since I cannot get all the elements of JSON response mapped to the innermost element from the response. Appreciate your support in providing useful suggestions.

Gson gson = new Gson();
                        DataResponse dataResponse = gson.fromJson(EntityUtils.toString(response.getEntity()),
                                DataResponse.class);
amar19
  • 373
  • 1
  • 3
  • 16
  • `private Map` - why `JsonElement` ? – Scary Wombat Oct 11 '18 at 01:29
  • @ScaryWombat It's another json string inside payload so I mapped it to JsonElement, plus it gives me this error if I map it to JsonObject or Array - Expected a com.google.gson.JsonObject but was com.google.gson.JsonPrimitive – amar19 Oct 11 '18 at 01:33
  • 1
    You need to create other POJO that you can embed in the DataResponse class e.g. a `PayLoad` class that contains a `List` of `Result` Objects - The Result Object will have `key$`, `score` and `to` fields – Scary Wombat Oct 11 '18 at 01:35
  • @ScaryWombat Okay I will try with creating classes for Payload and Result. But I was wondering is there simple way to do it using one Response POJO class, using nested maps or lists. – amar19 Oct 11 '18 at 01:39
  • @ScaryWombat the name for class should be $pyaload, right? To map it correctly to the field. However it gives the warning as -- [ Type name is discouraged. By convention, Java type names usually don't contain the $ character ] – amar19 Oct 11 '18 at 01:47

1 Answers1

0

While working with marshalling and unmarshalling, it is always good to have a model defined as:

public class DataResponse {

    private String $status;
    private Payload $payload;
   // getters and setters
}

class Payload {
    private String $nextStart;
    private List<Result> $results;

    // getters and setters
}


class Result {
    private String $key;
    private String score;
    private String to;

    // getters and setters
}

Now when you convert json to POJO as:

Gson gson = new Gson(); 
DataResponse dataResponse = gson.fromJson(EntityUtils.toString(response.getEntity()), DataResponse.class);

it can easily convert it.

Also, believe me, it is good for processing in your further code!

Update: if you really want to convert json to Map, then you can do something like this:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> myMap = gson.fromJson("{'key':'value'}", type);

Substitute json string there.

Yogen Rai
  • 2,961
  • 3
  • 25
  • 37
  • `score` and `to` do not have `$` – Scary Wombat Oct 11 '18 at 01:51
  • @ScaryWombat i didn't see those comments when i started to write this answer :) – Yogen Rai Oct 11 '18 at 01:55
  • @YogenRai Using TypeToken, I would have to create the key/value mapping for all the fields till innermost pair, right? Also what about JSONArray, do I need to create a list for it? – amar19 Oct 11 '18 at 01:59
  • @amar19 you can do `Map` and cast it later, but i won't recommend doing that as all API and resource should have proper contract defined!! :) – Yogen Rai Oct 11 '18 at 02:03
  • @YogenRai Okay, I'll go with the first method, it's very easy to do as well. Thanks a lot. – amar19 Oct 11 '18 at 02:06
  • @amar19 exactly!! and cost of creating all these models will save lot of work later when you want to play with this model! Good luck! would you mind upvoting/accepting if you like? ;) – Yogen Rai Oct 11 '18 at 02:08