Tôi đã xem xét Jackson, nhưng có vẻ như tôi sẽ phải chuyển đổi Bản đồ thành JSON, và sau đó kết quả là JSON thành POJO.Chuyển đổi một bản đồ <String, String> thành POJO
Có cách nào để chuyển đổi Bản đồ trực tiếp thành POJO không?
Tôi đã xem xét Jackson, nhưng có vẻ như tôi sẽ phải chuyển đổi Bản đồ thành JSON, và sau đó kết quả là JSON thành POJO.Chuyển đổi một bản đồ <String, String> thành POJO
Có cách nào để chuyển đổi Bản đồ trực tiếp thành POJO không?
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.
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).
cảm ơn - rất hữu ích. – user86834
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
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));
}}
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. –
Bạn có thể cung cấp lệnh gradle cho thư viện này không? –
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'' –
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