• Java中Map转对象


            在工作中遇到一个场景:从某数据库中拿到一批数据,拿到的形式是 List>,现有对应的自定义对象,假设为 User.class,但 Map 中的参数与 User 的属性并不是一一对应,且对某些特殊的字段要进行特殊处理。在此情况下,如何实现从 Map 到 User 对象的转换。

            正好趁这个机会,总结一下之前用到过的几种方法。

    一. 定义 User 对象与 Map

    1. @Data
    2. public class User {
    3. private String _key;
    4. private String _id;
    5. private String _rev;
    6. private String name;
    7. private String surname;
    8. private Boolean alive;
    9. private Integer age;
    10. private List traits;
    11. @JsonIgnore
    12. private String test;
    13. }

    @JsonIgnore 注解的作用是在 json 序列化时将被注解的属性忽略掉

    1. private static Map getMap() {
    2. Map map = new HashMap<>();
    3. map.put("_key", "qwertyui");
    4. map.put("_id", "ttt");
    5. map.put("_rev", "this is a test");
    6. map.put("name", "lizhou");
    7. map.put("surname", null);
    8. map.put("alive", true);
    9. map.put("age", 12);
    10. List list = new ArrayList<>();
    11. list.add("aaa");
    12. list.add("bbb");
    13. list.add("ccc");
    14. map.put("traits", list);
    15. map.put("test", "test");
    16. return map;
    17. }

    二.  五种转化方式

    1. private static void useBeanMap(Map map) {
    2. User user = new User();
    3. BeanMap beanMap = BeanMap.create(user);
    4. beanMap.putAll(map);
    5. System.out.println(user);
    6. }
    7. private static void useObjectMapper(Map map) {
    8. ObjectMapper objectMapper = new ObjectMapper();
    9. User user = objectMapper.convertValue(map, User.class);
    10. System.out.println(user);
    11. }
    12. //将map转化为json字符串,然后转为对象
    13. private static void useFastJson(Map map) {
    14. String s = JSON.toJSONString(map);
    15. User user = JSON.parseObject(s, User.class);
    16. System.out.println(user);
    17. }
    18. private static void useGson(Map map) {
    19. Gson gson = new Gson();
    20. String s = gson.toJson(map);
    21. User user = gson.fromJson(s, User.class);
    22. System.out.println(user);
    23. }
    24. private static void useField(Map map) {
    25. try {
    26. User user = new User();
    27. Field[] fields = User.class.getDeclaredFields();
    28. for (Field field : fields) {
    29. field.setAccessible(true);
    30. field.set(user, map.get(field.getName()));
    31. }
    32. System.out.println(user);
    33. } catch (IllegalAccessException e) {
    34. throw new RuntimeException(e);
    35. }
    36. }

    1. 调用以上五种方法,查看结果

    可以发现,都可以正常将 Map 转化为 User 对象,但是只有 ObjectMapper 方法会受到 @JsonIgnore 注解影响

    2. 删除 User 类部分属性

    将 User 类中的 test 属性注释掉

    1. @Data
    2. public class User {
    3. private String _key;
    4. private String _id;
    5. private String _rev;
    6. private String name;
    7. private String surname;
    8. private Boolean alive;
    9. private Integer age;
    10. private List traits;
    11. // @JsonIgnore
    12. // private String test;
    13. }

    再次调用方法,查看结果

    可以发现,除了 ObjectMapper 方法以外,其他方法都可以正常运行,ObjectMapper 方法会报错:

    1. Exception in thread "main" java.lang.IllegalArgumentException: Unrecognized field "test" (class com.example.demo.bean.User), not marked as ignorable (8 known properties: "_key", "_rev", "traits", "_id", "name", "alive", "age", "surname"])
    2. at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.example.demo.bean.User["test"])
    3. at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3922)
    4. at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3853)
    5. at com.example.demo.test.Test16.useObjectMapper(Test16.java:35)
    6. at com.example.demo.test.Test16.main(Test16.java:23)
    7. Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "test" (class com.example.demo.bean.User), not marked as ignorable (8 known properties: "_key", "_rev", "traits", "_id", "name", "alive", "age", "surname"])
    8. at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.example.demo.bean.User["test"])
    9. at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
    10. at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:840)
    11. at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1206)
    12. at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1592)
    13. at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1570)
    14. at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
    15. at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
    16. at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3917)
    17. ... 3 more

    所以 ObjectMapper 方法需要 Map 和转化对象的字段完全对应。

  • 相关阅读:
    [《考驾照》闲笔记事集]2012年8月28日
    C. Division(分解质因数)
    常见的java话题
    跑批SQL性能异常分析
    Java实体类与返给前端变量名字母大小写不一样问题
    VTK与OpenGL是什么,有什么关系?
    实习项目总结-Pandroid仿真数据管理平台
    pandas 笔记: interpolate
    Hystrix 部署
    面试算法 二叉树的遍历,方法 :迭代 ,前序遍历: 中序遍历: 后序遍历: 层序遍历
  • 原文地址:https://blog.csdn.net/qq_38736877/article/details/139474003