Patrzyłem na Jacksona, ale wydaje się, że musiałbym przekonwertować Mapę na JSON, a następnie wynikowy JSON na POJO.Konwertuj mapę <String, String> na POJO
Czy istnieje sposób na konwersję mapy bezpośrednio na POJO?
Patrzyłem na Jacksona, ale wydaje się, że musiałbym przekonwertować Mapę na JSON, a następnie wynikowy JSON na POJO.Konwertuj mapę <String, String> na POJO
Czy istnieje sposób na konwersję mapy bezpośrednio na POJO?
Cóż, możesz to osiągnąć także z Jacksonem. (i wydaje się być wygodniejszym, ponieważ rozważałeś użycie jacksona).
Zastosowanie ObjectMapper
„s convertValue
metoda:
final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
final MyPojo pojo = mapper.convertValue(map, MyPojo.class);
Nie ma potrzeby, aby przekształcić JSON ciąg lub coś innego; bezpośrednia konwersja działa znacznie szybciej.
Tak, zdecydowanie można uniknąć pośredniej konwersji na JSON. Za pomocą narzędzia do kopiowania głębokiego, takiego jak Dozer, możesz zamienić mapę bezpośrednio na POJO. Tutaj jest uproszczony przykład:
Przykład 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());
}
}
kod konwersji próbki:
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);
}
}
wyjściowa:
MyPojo [id = 5, nazwa = Bob wiek = 23, oszczędności = 2500.39]
Uwaga: Jeśli zmienisz mapę źródłową na Map<String, Object>
, możesz kopiować za pomocą dowolnie zagnieżdżonych właściwości (z Map<String, String>
dostajesz tylko jeden poziom).
dzięki - bardzo pomocne. – user86834
Jak możesz zrobić "głęboką kopię" z mapy do POJO? Powiedzmy na przykład, że masz klasę User.class, która zawiera klasę Address.class, a mapa ma klucz taki jak "address.city", "address.zip", a te muszą być odwzorowane na User.Address.City i User.Address.Zip ? Nie wydaje się, aby automatycznie interpretować kropkę w klawiszu Mapa jako pod-poziom do wykresu obiektu. – szxnyc
Ja testowałem zarówno Jacksona i BeanUtils i okazało się, że BeanUtils jest znacznie szybsze.
W moim komputerze (Windows 8.1, JDK1.7) otrzymałem ten wynik.
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));
}}
Różnica polega na tym, że Jackson ma z nim strukturę konwersji całego typu. na przykład "Mapa" zawiera 'map.put (" dane "," 2016-06-26 ")' a 'TestClass' ma pole' prywatne dane LocalDate; ', a następnie Jackson będzie w stanie załatwić sprawy, podczas gdy BeanUtils będzie zawieść. –
Czy możesz podać polecenie gradle dla tej biblioteki? –
Musisz dołączyć tę bibliotekę, aby użyć ObjectMapper 'compile 'com.fasterxml.jackson.core: jackson-databind: 2.7.3'' –
Używanie convertValue jest właściwą odpowiedzią, ale nie twórz instancji ObjectMapper za każdym razem. Tworzenie i bezpieczne tworzenie wątków jest kosztowne, więc utwórz je i przechowuj gdzieś w pamięci podręcznej. – glade