Ho guardato Jackson, ma sembra che dovrei convertire la mappa in JSON e quindi il JSON risultante nel POJO.Convertire una mappa <String, String> a un POJO
C'è un modo per convertire una mappa direttamente in un POJO?
Ho guardato Jackson, ma sembra che dovrei convertire la mappa in JSON e quindi il JSON risultante nel POJO.Convertire una mappa <String, String> a un POJO
C'è un modo per convertire una mappa direttamente in un POJO?
Bene, lo puoi fare anche con Jackson. (e sembra essere più comodo da quando stavi considerando l'utilizzo di Jackson).
Usa ObjectMapper
s' convertValue
metodo:
final ObjectMapper mapper = new ObjectMapper(); // jackson's objectmapper
final MyPojo pojo = mapper.convertValue(map, MyPojo.class);
Non c'è bisogno di convertire in stringa JSON o qualcos'altro; la conversione diretta è molto più veloce.
Sì, è sicuramente possibile evitare la conversione intermedia in JSON. Utilizzando uno strumento di copia profonda come Dozer puoi convertire la mappa direttamente in un POJO. Ecco un esempio semplicistico:
Esempio 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());
}
}
codice di conversione del campione:
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);
}
}
uscita:
MyPojo [id = 5, name = Bob, età = 23, risparmio = 2500.39]
Nota: se si modifica la mappa di origine su Map<String, Object>
, è possibile copiare proprietà nidificate a profondità arbitraria (con Map<String, String>
si ottiene solo un livello).
grazie - molto utile. – user86834
Come si può eseguire una "copia profonda" da Mappa a POJO? Supponiamo ad esempio che tu abbia una User.class che incapsula un Address.class e che la mappa abbia una chiave come "address.city", "address.zip" e che questi debbano mappare a User.Address.City e User.Address.Zip ? Non sembra interpretare automaticamente il punto nel tasto Mappa come sottolivello del grafico dell'oggetto. – szxnyc
Ho testato sia Jackson e BeanUtils e scoperto che BeanUtils è molto più veloce.
Nella mia macchina (Windows8.1, JDK1.7) ho ottenuto questo risultato.
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));
}}
La differenza è: Jackson ha un intero quadro di conversione di tipo con esso. per esempio. la 'Mappa' contiene' map.put ("data", "2016-06-26") 'e' TestClass' ha un campo 'Dati LocalDate privati;', quindi Jackson sarebbe in grado di fare le cose, mentre BeanUtils fallire. –
Puoi fornire il comando gradle per questa libreria? –
È necessario includere questa libreria per utilizzare ObjectMapper 'compile 'com.fasterxml.jackson.core: jackson-databind: 2.7.3'' –
Utilizzare convertValue è la risposta corretta, ma non creare un'istanza ObjectMapper ogni volta. È costoso da creare e sicuro per i thread, quindi creane uno e caricalo da qualche parte. – glade