2013-05-07 33 views

Trả lời

160

Vâng, bạn cũng có thể đạt được điều đó với Jackson. (và nó có vẻ là thoải mái hơn kể từ khi bạn đang xem xét sử dụng jackson). convertValue phương pháp

Sử dụng ObjectMapper 's:

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

Không cần phải chuyển đổi thành JSON chuỗi hay cái gì khác; chuyển đổi trực tiếp nhanh hơn nhiều.

+0

Bạn có thể cung cấp lệnh gradle cho thư viện này không? –

+2

Bạn cần phải bao gồm thư viện này để sử dụng ObjectMapper 'compile 'com.fasterxml.jackson.core: jackson-databind: 2.7.3'' –

+1

Sử dụng convertValue là câu trả lời đúng, nhưng không tạo một cá thể ObjectMapper mỗi lần. Đó là tốn kém để tạo ra và an toàn thread, do đó, tạo ra một và cache nó ở đâu đó. – glade

2

Có, chắc chắn có thể tránh chuyển đổi trung gian sang JSON. Sử dụng công cụ sao chép sâu như Dozer bạn có thể chuyển đổi bản đồ trực tiếp thành POJO. Dưới đây là một ví dụ đơn giản:

Ví dụ 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()); 
    } 
} 

mã chuyển đổi mẫu:

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

Output:

MyPojo [id = 5, name = Bob, tuổi tác = 23, tiết kiệm = 2500,39]

Lưu ý: Nếu bạn thay đổi bản đồ nguồn thành Map<String, Object> thì bạn có thể sao chép qua các thuộc tính lồng nhau sâu tùy ý (với Map<String, String> bạn chỉ nhận được một cấp).

+0

cảm ơn - rất hữu ích. – user86834

+1

Làm cách nào để bạn có thể thực hiện "bản sao sâu" từ Bản đồ đến POJO? Ví dụ, bạn có một User.class đóng gói một Address.class và bản đồ có một khóa như "address.city", "address.zip" và những thứ này cần ánh xạ tới User.Address.City và User.Address.Zip ? Dường như không tự động diễn giải dấu chấm trong khóa Bản đồ dưới dạng cấp phụ thành biểu đồ đối tượng. – szxnyc

20

Một giải pháp với Gson:

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

Tuyệt vời !!!!!!!! – TechBee

3

Tôi đã thử nghiệm cả hai Jackson và BeanUtils và phát hiện ra rằng BeanUtils là nhanh hơn nhiều.
Trong máy của tôi (Windows8.1, JDK1.7) Tôi nhận được kết quả này.

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

Sự khác biệt là: Jackson có một khung chuyển đổi toàn bộ kiểu với nó. ví dụ. 'Map' chứa' map.put ("dữ liệu", "2016-06-26") 'và' TestClass' có một trường dữ liệu 'LocalDate riêng;', sau đó Jackson có thể hoàn thành công việc, trong khi BeanUtils sẽ Thất bại. –

Các vấn đề liên quan