2013-05-07 5 views

답변

160

글쎄, 당신도 잭슨과 함께 할 수 있습니다. (잭슨 사용을 고려한 이후로 더 편하게 보입니다).

사용 ObjectMapperconvertValue 방법 :

final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper 
final MyPojo pojo = mapper.convertValue(map, MyPojo.class); 

JSON 문자열이나 다른 무언가로 변환 할 필요가 없습니다; 직접 변환이 훨씬 빠릅니다.

+0

이 라이브러리에 대해 gradle 명령을 제공 할 수 있습니까? –

+2

ObjectMapper 'compile'com.fasterxml.jackson.core를 사용하려면이 라이브러리를 포함해야합니다. jackson-databind : 2.7.3'' –

+1

convertValue를 사용하는 것이 옳은 답변이지만 매번 ObjectMapper 인스턴스를 만들지는 마십시오. 생성하기 쉽고 스레드로부터 안전하기 때문에 생성하고 어딘가에 캐시하십시오. – glade

2

예, JSON으로의 중간 변환을 피할 수 있습니다. Dozer과 같은 딥 복사 도구를 사용하면지도를 POJO로 직접 변환 할 수 있습니다.

예 POJO :

public class MyPojo implements Serializable { 
    private static final long serialVersionUID = 1L; 

    private String id; 
    private String name; 
    private Integer age; 
    private Double savings; 

    public MyPojo() { 
     super(); 
    } 

    // Getters/setters 

    @Override 
    public String toString() { 
     return String.format(
       "MyPojo[id = %s, name = %s, age = %s, savings = %s]", getId(), 
       getName(), getAge(), getSavings()); 
    } 
} 

샘플 전환 코드 :

public class CopyTest { 
    @Test 
    public void testCopyMapToPOJO() throws Exception { 
     final Map<String, String> map = new HashMap<String, String>(4); 
     map.put("id", "5"); 
     map.put("name", "Bob"); 
     map.put("age", "23"); 
     map.put("savings", "2500.39"); 
     map.put("extra", "foo"); 

     final DozerBeanMapper mapper = new DozerBeanMapper(); 
     final MyPojo pojo = mapper.map(map, MyPojo.class); 
     System.out.println(pojo); 
    } 
} 

출력 :

MyPojo [ID = 5 명 = 밥, 연령 여기서 단순한 예이며 = 23, 절약 = 2500.39]

참고 : 소스 맵을 Map<String, Object>으로 변경하면 임의의 깊은 중첩 된 속성을 복사 할 수 있습니다 (Map<String, String>은 한 레벨 만 가져옵니다).

+0

감사 - 매우 유용합니다. – user86834

+1

지도에서 POJO로 "딥 카피"를 어떻게 할 수 있습니까? 예를 들어, Address.class를 캡슐화하는 User.class가 있고지도에 "address.city", "address.zip"와 같은 키가 있고 User.Address.City 및 User.Address.Zip에 매핑 할 필요가 있다고 가정 해 보겠습니다. ? Map 키의 점을 오브젝트 그래프의 하위 레벨로 자동 해석하지 않는 것 같습니다. – szxnyc

20

Gson있는 솔루션 : 나는 잭슨과 BeanUtils를 모두 테스트 BeanUtils 훨씬 빠르다는 것을 발견했다

Gson gson = new Gson(); 
JsonElement jsonElement = gson.toJsonTree(map); 
MyPojo pojo = gson.fromJson(jsonElement, MyPojo.class); 
+1

굉장 !!!!!!!! – TechBee

3

.
내 컴퓨터 (Windows8.1, JDK1.7)에서이 결과가 나타납니다.

BeanUtils t2-t1 = 286 
Jackson t2-t1 = 2203 


public class MainMapToPOJO { 

public static final int LOOP_MAX_COUNT = 1000; 

public static void main(String[] args) { 
    Map<String, Object> map = new HashMap<>(); 
    map.put("success", true); 
    map.put("data", "testString"); 

    runBeanUtilsPopulate(map); 

    runJacksonMapper(map); 
} 

private static void runBeanUtilsPopulate(Map<String, Object> map) { 
    long t1 = System.currentTimeMillis(); 
    for (int i = 0; i < LOOP_MAX_COUNT; i++) { 
     try { 
      TestClass bean = new TestClass(); 
      BeanUtils.populate(bean, map); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } catch (InvocationTargetException e) { 
      e.printStackTrace(); 
     } 
    } 
    long t2 = System.currentTimeMillis(); 
    System.out.println("BeanUtils t2-t1 = " + String.valueOf(t2 - t1)); 
} 

private static void runJacksonMapper(Map<String, Object> map) { 
    long t1 = System.currentTimeMillis(); 
    for (int i = 0; i < LOOP_MAX_COUNT; i++) { 
     ObjectMapper mapper = new ObjectMapper(); 
     TestClass testClass = mapper.convertValue(map, TestClass.class); 
    } 
    long t2 = System.currentTimeMillis(); 
    System.out.println("Jackson t2-t1 = " + String.valueOf(t2 - t1)); 
}} 
+0

차이점은 Jackson은 전체 유형 변환 프레임 워크가 있습니다. 예 : 'Map'은'map.put ("data", "2016-06-26")'을 포함하고'TestClass'는'private LocalDate data;'필드를 가지고 있습니다. 그러면 Jackson은 일을 끝내고 BeanUtils는 실패. –

관련 문제