web-dev-qa-db-fra.com

Convertir une carte <String, String> en un POJO

Je me suis tourné vers Jackson, mais il me semble que je devrais convertir la carte en JSON, puis le JSON résultant en POJO.

Existe-t-il un moyen de convertir une carte directement en POJO?

144
user86834

Eh bien, vous pouvez y parvenir avec Jackson. (et cela semble être plus confortable depuis que vous envisagiez d’utiliser jackson).

Utilisez ObjectMapper ' convertValue méthode:

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

Pas besoin de convertir en chaîne JSON ou autre chose; La conversion directe est beaucoup plus rapide.

281
Jongwook Choi

Une solution avec Gson :

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

J'ai testé Jackson et BeanUtils et découvert que BeanUtils est beaucoup plus rapide.
Sur ma machine (Windows8.1, JDK1.7), j’ai eu ce résultat.

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

Oui, il est tout à fait possible d'éviter la conversion intermédiaire en JSON. En utilisant un outil de copie en profondeur tel que Dozer , vous pouvez convertir la carte directement en POJO. Voici un exemple simpliste:

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

Exemple de code de conversion:

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

Sortie:

MyPojo [id = 5, nom = Bob, âge = 23 ans, économies = 2500,39]

Remarque: Si vous modifiez votre carte source en un Map<String, Object>, vous pouvez alors copier des propriétés imbriquées de manière arbitraire (avec Map<String, String>, vous n'obtenez qu'un niveau).

3
Perception

si vous avez des types génériques dans votre classe, vous devez utiliser TypeReference avec convertValue().

final ObjectMapper mapper = new ObjectMapper();
final MyPojo<MyGenericType> pojo = mapper.convertValue(map, new TypeReference<MyPojo<MyGenericType>>() {});

Vous pouvez aussi l'utiliser pour convertir un pojo en Java.util.Map back.

final ObjectMapper mapper = new ObjectMapper();
final Map<String, Object> map = mapper.convertValue(pojo, new TypeReference<Map<String, Object>>() {});
2
bhdrk

convertir Map en exemple POJO. Remarquez que la clé Map contient le soulignement et que la variable de champ est bosse.

User.class POJO

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

@Data
public class User {
    @JsonProperty("user_name")
    private String userName;
    @JsonProperty("pass_Word")
    private String passWord;
}

Le test App.class l'exemple

import Java.util.HashMap;
import Java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;

public class App {
    public static void main(String[] args) {
        Map<String, String> info = new HashMap<>();
        info.put("user_name", "Q10Viking");
        info.put("pass_Word", "123456");

        ObjectMapper mapper = new ObjectMapper();
        User user = mapper.convertValue(info, User.class);

        System.out.println("-------------------------------");
        System.out.println(user);
    }
}
/**output
-------------------------------
User(userName=Q10Viking, passWord=123456)
 */
0
黄壮壮