Конвертация карты в POJO-объект


Я смотрел на Джексона, но, похоже, мне придется преобразовать карту в JSON, а затем полученный JSON в POJO.

есть ли способ конвертировать карту непосредственно в POJO?

4 100

4 ответа:

хорошо, вы можете достичь этого с Джексоном тоже. (и это кажется более удобным, так как вы рассматривали возможность использования Джексона).

использовать ObjectMapper ' s convertValue способ:

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

нет необходимости конвертировать в строку JSON или что-то еще; прямое преобразование делает гораздо быстрее.

решение Gson:

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

Я проверил как Джексон, так и BeanUtils и выяснил, что BeanUtils намного быстрее.
В моей машине (Windows8.1 , JDK1.7) я получил этот результат.

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

да, его определенно можно избежать промежуточного преобразования в JSON. С помощью инструмента глубокого копирования, как бульдозер вы можете конвертировать карту непосредственно в POJO. Вот упрощенный пример:

пример 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());
    }
}

пример преобразования кода:

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

выход:

MyPojo[id = 5, name = Bob, age = 23, savings = 2500.39]

Примечание: Если вы измените исходную карту на Map<String, Object> затем вы может копировать произвольно глубокие вложенные свойства (с Map<String, String> вы получаете только один уровень).