2011-08-12 3 views
24

나는 stackoverflow에서 몇 가지 질문과 비슷한 질문이 있지만 아무도 정말 내 문제에 대답. 나는 잭슨의 ObjectMapper 사용하여 사용자 개체의 목록에이 JSON 문자열을 구문 분석 할 : 잭슨 JSON + 자바 제네릭 얻을 LinkedHashMap

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

가이 같은 내부 클래스를 정의 :

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; 
    } 
} 

목록에 JSON 문자열을 구문 분석하기

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; 
} 

는하지만 내가 돌아올 것은 LinkedHashMapsList입니다 : UserRoles의 난 제네릭을 사용합니다.

내 코드가 잘못되었습니다.

+1

그것은 자바 언어, 악명 높은 유형의 삭제입니다 : 거기에 T는 타입의 변수와 정의를 입력하지; 기본적으로 List 을 요청하고 있음을 의미합니다. 그런 다음 Jackson은 '자연스러운'객체 유형을 사용하여 JSON을 바인딩하고 JSON 객체는 Map (순서 지정을 유지하는 LinkedHashMap 유형)이됩니다. 클래스를 전달하여 문제를 올바르게 해결 한 다음 실제 유형을 정의합니다. – StaxMan

답변

30

StaxMan의 조언에 따라 다음은 더 이상 사용되지 않는 정적 collectionType() 메서드를 사용하지 않습니다.

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(new UserRole(),s,UserRole.class); 

    } 

    protected static <T> List<T> mapJsonToObjectList(T typeDef,String json,Class 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 + "]"; 
    } 

} 

출력 ...

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 
+2

수정. 한 가지 사소한 점은 비추천 문제를 해결하기 위해 'objectMapper.getTypeFactory()'를 호출하여 비 정적 메서드를 사용할 수 있다는 것입니다. Jackson 1.8에서이 변경 (스칼라와 같은 JVM 언어를 지원하는 데는 자신의 Collection/Map 유형이 필요함) ... – StaxMan

+0

@StaxMan - 비 사용 중지 메소드를 포함하도록 업데이트 됨 – nsfyn55

+1

@ nsfyn55 답변에 두 개의 main 그 종류의 질문에 대한 점수. 'T'를 사용하고 비추천 된 방법으로 처리합니다. 투표하기. – kamaci