14

I am facing a problem , sometimes Json response returns an array of objects , sometimes object itself , how we can handle dynamically in the response class. In the current eg :results sometimes gets an array of objects

 "\"results\": " +
            "[{" +

and sometimes object itself

 "\"results\": " +
            "{" +

Eg:

How we can handle this ?

Gson gson = new Gson();
    SearchResponse response=new SearchResponse();
    response= gson.fromJson("{" +
            "\"completed_in\": 0.047," +
            "\"max_id\": 291771567376039936," +
            "\"max_id_str\": \"291771567376039936\"," +
            "\"next_page\": \"?page=2&max_id=291771567376039936&q=javacodegeeks\"," +
            "\"page\": 1," +
            "\"query\": \"javacodegeeks\"," +
            "\"refresh_url\": \"?since_id=291771567376039936&q=javacodegeeks\"," +
            "\"results\": " +
            "{" +
            "\"created_at\": \"Thu, 17 Jan 2013 04:58:57 +0000\"," +
            "\"from_user\": \"hkokko\"," +
            "\"from_user_id\": 24726686," +
            "\"from_user_id_str\": \"24726686\"," +
            " \"from_user_name\": \"Hannu Kokko\"," +
            " \"geo\": null," +
            "\"id\": 291771567376039936," +
            "\"id_str\": \"291771567376039936\"," +
            "\"iso_language_code\": \"en\"," +
            " \"metadata\": {" +
            "\"result_type\": \"recent\"}," +
            "\"profile_image_url\": \"hjh\"," +
            "\"profile_image_url_https\": \"kkj\"," +
            "\"source\": \"<a href="hj;\"," +
            "\"text\": \"Continuous Deployment: Are You Afraid It Might Work? jh\"," +
            "\"to_user\": null," +
            "\"to_user_id\": 0," +
            "\"to_user_id_str\": \"0\"," +
            "\"to_user_name\": null" +
            " }," +
            "\"results_per_page\": 15," +
            "\"since_id\": 0," +
            "\"since_id_str\": \"0\"" +
            "}", SearchResponse.class);
    System.out.println(response.toString());

Kindly assist...

Can anyone give any suggestions by using different jars to achieve this?

4
  • Such server realisation is real NOT good one. It's yours back-end? Commented Jan 17, 2013 at 6:49
  • its client, i receive this response from server.. Commented Jan 17, 2013 at 6:57
  • If the server returns an array of object does it always contain a single object or can contain multiple ones ? If it's an array do you proccess every element of it? Commented Jan 17, 2013 at 12:22
  • Have a look at this question stackoverflow.com/questions/16654042/… Commented Aug 16, 2014 at 4:13

2 Answers 2

18

i found a solution for this ,i felt to share this..The code will automatically convert ..if excepted response is arraylist in response class....then if object is coming in response then add to arraylist else if arraylist it will take the same list. we need hook change the response bfore it calls fromJson.

public class ArrayAdapter<T> extends TypeAdapter<List<T>> {
    private Class<T> adapterclass;

    public ArrayAdapter(Class<T> adapterclass) {

        this.adapterclass = adapterclass;
    }

    public List<T> read(JsonReader reader) throws IOException {


        List<T> list = new ArrayList<T>();

        Gson gson = new Gson();

        if (reader.peek() == JsonToken.BEGIN_OBJECT) {

            T inning = (T) gson.fromJson(reader, adapterclass);
            list.add(inning);

        } else if (reader.peek() == JsonToken.BEGIN_ARRAY) {

            reader.beginArray();
            while (reader.hasNext()) {
                T inning = (T) gson.fromJson(reader, adapterclass);
                list.add(inning);
            }
            reader.endArray();

        } else {
            reader.skipValue();
        }

        return list;
    }

    public void write(JsonWriter writer, List<T> value) throws IOException {

    }

}

public class ArrayAdapterFactory implements TypeAdapterFactory {

  @SuppressWarnings({ "unchecked" })
  @Override
  public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {

      ArrayAdapter typeAdapter = null;
      try {
          if (type.getRawType() == List.class)
          {

              typeAdapter = new ArrayAdapter(
                      (Class) ((ParameterizedType) type.getType())
                              .getActualTypeArguments()[0]);
          }
      } catch (Exception e) {
          e.printStackTrace();
      }

      return typeAdapter;
}

then just call

 Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();
 SearchResponse response;
 esponse= gson.fromJson("your json string", SearchResponse.class)
Sign up to request clarification or add additional context in comments.

2 Comments

it gives error at TypeAdapter<T> typeAdapter = null; for <T>.. You can resolve this issue by modifying the class signature like public class ArrayAdapterFactory<T> implements TypeAdapterFactory {
com.google.gson.internal.$Gson$Types$ParameterizedTypeImpl cannot be cast to java.lang.Class at am getting error while mapping using the above example
4

You would need to write a custom deserializer that checks the type of results in the JSON then acts accordingly.

Your POJO will contain an array for results and if your incoming JSON only has a single object you'll need to fix that. One way is to modify the JSON then deserialize it:

class SearchResponseDeserializer implements JsonDeserializer<SearchResponse> {
  public SearchResponse deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {

    if (json.getAsJsonObject().get("results").isJsonObject()) {
      //modify JSON: change results to be an array
      // ...
    }

    return new Gson().fromJson(json, SearchResults.class);

  }
}

Or, fix the server, of course. It should always be returning an array to avoid this issue.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.