0

I am trying to store a json array response into an arraylist. Here is what the JSON response looks like:

"identityList":{
    "identity":[
        {
            "firstName":"MICHAEL",
            "lastName":"JAMESON",
            "gender":"MALE",
            "dateOfBirth":"1961-05-18T00:00:00.000+0000",
        },
        {
            "firstName":"KELLY",
            "lastName":"JAMESON",
            "gender":"FEMALE",
            "dateOfBirth":"1951-04-01T00:00:43.000+0000",
        }
    ]
}

Here's the Identity class:

public class Identity {
    /** The first name. */
    private String firstName;

    /** the middleName. */
    private String middleName;

    /** the lastName. */
    private String lastName;

    /** the dateOfBirth. */
    private LocalDate dateOfBirth;

    public Identity(String firstName, String middleName, String lastName, LocalDate dateOfBirth) {
        super();
        this.firstName = firstName;
        this.middleName = middleName;
        this.lastName = lastName;
        this.dateOfBirth = dateOfBirth;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getMiddleName() {
        return middleName;
    }

    public String getLastName() {
        return lastName;
    }

    public LocalDate getDateOfBirth() {
        return dateOfBirth;
    }
}

Based on what I've found on other SO posts like here I wrote this function to parse it:

public static <T> T getResponseObjectAsArray(String resourceResponse, String jsonObject, final Class<T> responseClass) {
    Type listType = new TypeToken<List<responseClass>>(){}.getType();
    JSONArray jsonResponse = new JSONObject(resourceResponse).getJSONArray(jsonObject);
    return gson.fromJson(jsonResponse, listType);
}

And calling it like this:

getResponseObjectAsArray(resourceResponse, "identityList", Identity.class)

With resourceResponse being the json response in a string format. But I get a syntax error with the getResponseObjectAsArray method that says:

Error:(39, 44) java: cannot find symbol
  symbol:   class responseClass

I'm trying to parametrize the list with whatever class passed into the method because it could be a list of many other types and not just Identity. What am i doing wrong here?

Edit 1: Tried the solution of List<T> and got this error now:

Error:(41, 20) java: no suitable method found for fromJson(org.json.JSONArray,java.lang.reflect.Type)
    method com.google.gson.Gson.<T>fromJson(java.lang.String,java.lang.Class<T>) is not applicable
      (cannot infer type-variable(s) T
        (argument mismatch; org.json.JSONArray cannot be converted to java.lang.String))
    method com.google.gson.Gson.<T>fromJson(java.lang.String,java.lang.reflect.Type) is not applicable
      (cannot infer type-variable(s) T
        (argument mismatch; org.json.JSONArray cannot be converted to java.lang.String))
    method com.google.gson.Gson.<T>fromJson(java.io.Reader,java.lang.Class<T>) is not applicable
      (cannot infer type-variable(s) T
        (argument mismatch; org.json.JSONArray cannot be converted to java.io.Reader))
    method com.google.gson.Gson.<T>fromJson(java.io.Reader,java.lang.reflect.Type) is not applicable
      (cannot infer type-variable(s) T
        (argument mismatch; org.json.JSONArray cannot be converted to java.io.Reader))
    method com.google.gson.Gson.<T>fromJson(com.google.gson.stream.JsonReader,java.lang.reflect.Type) is not applicable
      (cannot infer type-variable(s) T
        (argument mismatch; org.json.JSONArray cannot be converted to com.google.gson.stream.JsonReader))
    method com.google.gson.Gson.<T>fromJson(com.google.gson.JsonElement,java.lang.Class<T>) is not applicable
      (cannot infer type-variable(s) T
        (argument mismatch; org.json.JSONArray cannot be converted to com.google.gson.JsonElement))
    method com.google.gson.Gson.<T>fromJson(com.google.gson.JsonElement,java.lang.reflect.Type) is not applicable
      (cannot infer type-variable(s) T
        (argument mismatch; org.json.JSONArray cannot be converted to com.google.gson.JsonElement))

Edit 2: Here's another attempt at parametrizing a list object:

public static <T> List<T> getResponseObjectAsArray(String resourceResponse, String jsonObject, Class<T> responseClass) {
    JSONArray jsonResponse = new JSONObject(resourceResponse).getJSONObject("identityList").getJSONArray(jsonObject);
    return gson.fromJson(jsonResponse.toString(), List<responseClass>);
}

I just hardcoded the identityList string for now but later I'll make it as user input. But I'm still unable to parametrize the list inside of the fromJson call. I'm getting an Expression expected error.

Community
  • 1
  • 1
Richard
  • 5,840
  • 36
  • 123
  • 208
  • TypeToken>(){}.getType(); where is the responseClass defined? Either use a wildcard or exact class definition – Shriram Feb 08 '16 at 16:41

3 Answers3

1

Thanks to this post I figured out how to implement what I want. Here's the code now:

public static <T> List<T> getResponseObjectAsArray(String resourceResponse, String jsonObject, Class<T> responseClass) {
    List<T> list = new ArrayList<T>();
    try {
        list.add(responseClass.getConstructor().newInstance());
    } catch(Exception e) {
        throw new RuntimeException(e);
    }
    JSONArray jsonResponse = new JSONObject(resourceResponse).getJSONObject("identityList").getJSONArray(jsonObject);
    return gson.fromJson(jsonResponse.toString(), list.getClass());
}

There's still stuff to fix like proper error handling and not hard coding the getJson value.

Community
  • 1
  • 1
Richard
  • 5,840
  • 36
  • 123
  • 208
0

The line giving you the issue is this one:

Type listType = new TypeToken<List<responseClass>>(){}.getType();

Since responseClass is an object. Type checking in Java is a static thing, so it does not accept a class object as a specialization parameter for List. You could fix this by simply changing it to the statically known type T:

Type listType = new TypeToken<List<T>>(){}.getType();

Edit

getResponseObjectAsArray should return an array of T, not a single element T. The problem is in getting the class of an array of generic types, due to type erasure.

@SuppressWarnings("unchecked")
public static <T> T[] getArray(String json, String field, final Class<T> clazz) {
    JSONArray array = new JSONObject(json).getJSONArray(field);
    try {
        Class<T[]> arrayClass = (Class<T[]>) Class.forName("[L" + clazz.getName() + ";");
        return gson.fromJson(array, arrayClass);
    } catch(ClassNotFoundException e) {
        // If T.class exists, then T[].class should also exist, so this should never be reached
        throw new RuntimeException(e);
    }
}
Andrew Williamson
  • 8,299
  • 3
  • 34
  • 62
  • No, it's java's weird way of [specifying an array](http://stackoverflow.com/questions/5085889/l-array-notation-where-does-it-come-from). – Andrew Williamson Feb 08 '16 at 17:45
  • I tried this and I got the same error respones as above. `No suitable method found for fromJson(org.json.JSONArray, java.lang.class)` – Richard Feb 08 '16 at 17:48
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/102923/discussion-between-andrew-williamson-and-richard). – Andrew Williamson Feb 08 '16 at 17:49
0

String jsonResultString = sb.toString(); ArrayList crawlerList = gson.fromJson(jsonResultString, new TypeToken>() {}.getType());

or try read this http://androidengineer.weebly.com/tutorials/json-to-gson-to-java-with-httpurlconnection-in-android @SerializedName(firstName) private String firstName;

@SerializedName("firstName")
private String middleName;

@SerializedName("lastName")
private String lastName;

@SerializedName("gender")
private LocalDate dateOfBirth;

end ect....

Trunks ssj
  • 91
  • 1
  • 5