我一直在看杰克逊,但似乎我必须将地图转换为JSON,然后将结果JSON转换为POJO。

是否有方法将Map直接转换为POJO?


当前回答

ObjectMapper objectMapper = new ObjectMapper();
// Use this if all properties are not in the class
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final MyPojo pojo = objectMapper.convertValue(map, MyPojo.class);

与第一个答案相同,但我得到了一个错误使用,因为我不希望Map的所有属性转换为类。我还找到了objectmap .configure(反序列化特性。FAIL_ON_UNKNOWN_PROPERTIES、假);作为解决方案。

其他回答

我对Jackson和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));
}}

杰克逊也能做到这一点。(而且自从你考虑使用jackson后,它似乎更舒服)。

使用ObjectMapper的convertValue方法:

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

不需要转换成JSON字符串或其他东西;直接转换要快得多。

是的,它绝对可以避免到JSON的中间转换。使用像Dozer这样的深度复制工具,你可以直接将地图转换为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,名字= Bob,年龄= 23,存款= 2500.39]

注意:如果你将源映射更改为map <String, Object>,那么你可以复制任意深度嵌套的属性(使用map <String, String>,你只能得到一层)。

将Map转换为POJO的例子。注意Map键包含下划线,字段变量是驼峰。

用户阶层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;
}

class测试这个例子

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)
 */
ObjectMapper objectMapper = new ObjectMapper();
// Use this if all properties are not in the class
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
final MyPojo pojo = objectMapper.convertValue(map, MyPojo.class);

与第一个答案相同,但我得到了一个错误使用,因为我不希望Map的所有属性转换为类。我还找到了objectmap .configure(反序列化特性。FAIL_ON_UNKNOWN_PROPERTIES、假);作为解决方案。