Java中Map转对象

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

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

一. 定义 User 对象与 Map

java 复制代码
@Data
public class User {

    private String _key;

    private String _id;

    private String _rev;

    private String name;

    private String surname;

    private Boolean alive;

    private Integer age;

    private List<String> traits;

    @JsonIgnore
    private String test;

}

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

java 复制代码
private static Map<String, Object> getMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("_key", "qwertyui");
        map.put("_id", "ttt");
        map.put("_rev", "this is a test");
        map.put("name", "lizhou");
        map.put("surname", null);
        map.put("alive", true);
        map.put("age", 12);
        List<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        map.put("traits", list);
        map.put("test", "test");
        return map;
    }

二. 五种转化方式

java 复制代码
    private static void useBeanMap(Map<String, Object> map) {
        User user = new User();
        BeanMap beanMap = BeanMap.create(user);
        beanMap.putAll(map);
        System.out.println(user);
    }

    private static void useObjectMapper(Map<String, Object> map) {
        ObjectMapper objectMapper = new ObjectMapper();
        User user = objectMapper.convertValue(map, User.class);
        System.out.println(user);
    }

    //将map转化为json字符串,然后转为对象
    private static void useFastJson(Map<String, Object> map) {
        String s = JSON.toJSONString(map);
        User user = JSON.parseObject(s, User.class);
        System.out.println(user);
    }

    private static void useGson(Map<String, Object> map) {
        Gson gson = new Gson();
        String s = gson.toJson(map);
        User user = gson.fromJson(s, User.class);
        System.out.println(user);
    }

    private static void useField(Map<String, Object> map) {
        try {
            User user = new User();
            Field[] fields = User.class.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                field.set(user, map.get(field.getName()));
            }
            System.out.println(user);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

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

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

2. 删除 User 类部分属性

将 User 类中的 test 属性注释掉

java 复制代码
@Data
public class User {

    private String _key;

    private String _id;

    private String _rev;

    private String name;

    private String surname;

    private Boolean alive;

    private Integer age;

    private List<String> traits;

//    @JsonIgnore
//    private String test;

}

再次调用方法,查看结果

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

java 复制代码
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"])
 at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.example.demo.bean.User["test"])
	at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3922)
	at com.fasterxml.jackson.databind.ObjectMapper.convertValue(ObjectMapper.java:3853)
	at com.example.demo.test.Test16.useObjectMapper(Test16.java:35)
	at com.example.demo.test.Test16.main(Test16.java:23)
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"])
 at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.example.demo.bean.User["test"])
	at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61)
	at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:840)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1206)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1592)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1570)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:294)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
	at com.fasterxml.jackson.databind.ObjectMapper._convert(ObjectMapper.java:3917)
	... 3 more

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

相关推荐
卓码软件测评1 分钟前
第三方软件测试机构【性能测试工具用LoadRunner还是JMeter?】
java·功能测试·测试工具·jmeter·性能优化
Lionel_SSL3 小时前
《深入理解Java虚拟机》第三章读书笔记:垃圾回收机制与内存管理
java·开发语言·jvm
记得开心一点嘛4 小时前
手搓Springboot
java·spring boot·spring
老华带你飞4 小时前
租房平台|租房管理平台小程序系统|基于java的租房系统 设计与实现(源码+数据库+文档)
java·数据库·小程序·vue·论文·毕设·租房系统管理平台
独行soc4 小时前
2025年渗透测试面试题总结-66(题目+回答)
java·网络·python·安全·web安全·adb·渗透测试
脑子慢且灵4 小时前
[JavaWeb]模拟一个简易的Tomcat服务(Servlet注解)
java·后端·servlet·tomcat·intellij-idea·web
华仔啊5 小时前
SpringBoot 中 6 种数据脱敏方案,第 5 种太强了,支持深度递归!
java·后端
异常驯兽师6 小时前
Spring 中处理 HTTP 请求参数注解全解析
java·spring·http
连合机器人7 小时前
晨曦中的守望者:当科技为景区赋予温度
java·前端·科技
AD钙奶-lalala7 小时前
idea新建的项目new 没有java class选项
java·ide·intellij-idea