Search code examples
javagenericsjacksongeneric-listlinkedhashmap

Jackson JSON + Java Generics get LinkedHashMap


I have a question which is similar to some questions at stackoverflow but none really answer my problem. I use the ObjectMapper of Jackson and want to parse this JSON string into an List of User objects:

[{ "user" : "Tom", "role" : "READER" }, 
 { "user" : "Agnes", "role" : "MEMBER" }]

I define an inner class like this:

public class UserRole {

    private String user
    private String role;

    public void setUser(String user) {
        this.user = user;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getUser() {
        return user;
    }

    public String getRole() {
        return role;
    }
}

To parse the JSON String to an List of UserRoles I use generics:

protected <T> List<T> mapJsonToObjectList(String json) throws Exception {
    List<T> list;
    try {
        list = mapper.readValue(json, new TypeReference<List<T>>() {});
    } catch (Exception e) {
        throw new Exception("was not able to parse json");
    }
    return list;
}

But what I get back is a List of LinkedHashMaps.

What is wrong with my code?


Solution

  • The following works and as per StaxMan's advice no longer uses the deprecated static collectionType() method.

    public class SoApp
    {
    
       /**
        * @param args
        * @throws Exception
        */
       public static void main(String[] args) throws Exception
       {
          System.out.println("Hello World!");
    
          String s = "[{\"user\":\"TestCity\",\"role\":\"TestCountry\"},{\"user\":\"TestCity\",\"role\":\"TestCountry\"}]";
          StringReader sr = new StringReader("{\"user\":\"TestCity\",\"role\":\"TestCountry\"}");
          //UserRole user = mapper.readValue(sr, UserRole.class);
    
          mapJsonToObjectList(s,UserRole.class);
    
       }
    
       protected static <T> List<T> mapJsonToObjectList(String json, Class<T> clazz) throws Exception
       {
          List<T> list;
          ObjectMapper mapper = new ObjectMapper();
          System.out.println(json);
          TypeFactory t = TypeFactory.defaultInstance();
          list = mapper.readValue(json, t.constructCollectionType(ArrayList.class,clazz));
    
          System.out.println(list);
          System.out.println(list.get(0).getClass());
          return list;
       }
    }
    

    ...

    public class UserRole{
    
       private String user;
       private String role;
    
       public void setUser(String user) {
           this.user = user;
       }
    
       public void setRole(String role) {
           this.role = role;
       }
    
       public String getUser() {
           return user;
       }
    
       public String getRole() {
           return role;
       }
    
       @Override
       public String toString()
       {
          return "UserRole [user=" + user + ", role=" + role + "]";
       }
       
    }
    

    output...

     Hello World!
    [{"user":"TestCity","role":"TestCountry"},{"user":"TestCity","role":"TestCountry"}]
    [UserRole [user=TestCity, role=TestCountry], UserRole [user=TestCity, role=TestCountry]]
    class com.test.so.fix.UserRole