You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在保留类型的前提下将POJO转换为Map?

解决POJO转Map保留原始类型的简便方法

这个问题我之前也遇到过!ObjectMapper默认处理Timestamp这类特殊类型时,确实会自动转成字符串或者时间戳Long,没法保留原始类型。不过不用自己写反射,有几个现成的工具可以直接搞定:

1. 使用Spring的BeanWrapper(推荐,无额外依赖如果已经用Spring)

Spring框架自带的BeanWrapper已经帮我们封装好了反射逻辑,能直接获取POJO属性的原始类型值,完全不用自己写复杂的反射代码。

示例代码:

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.util.HashMap;
import java.util.Map;

public class PojoMapConverter {
    public static Map<String, Object> pojoToMap(Object pojo) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(pojo);
        Map<String, Object> resultMap = new HashMap<>();
        
        // 遍历所有属性描述符,跳过class属性
        for (String propertyName : beanWrapper.getPropertyDescriptors()) {
            if (!"class".equals(propertyName)) {
                resultMap.put(propertyName, beanWrapper.getPropertyValue(propertyName));
            }
        }
        return resultMap;
    }
}

用这个方法转换后,POJO里的Timestamp属性在Map里还是Timestamp类型,和原对象完全一致。

2. 使用Apache Commons PropertyUtils

如果你项目里已经引入了Apache Commons BeanUtils依赖,PropertyUtils.describe()方法可以直接返回保留原始类型的Map:

示例代码:

import org.apache.commons.beanutils.PropertyUtils;
import java.util.Map;

public class PojoMapConverter {
    public static Map<String, Object> pojoToMap(Object pojo) throws Exception {
        Map<String, Object> resultMap = PropertyUtils.describe(pojo);
        // 移除自动生成的class键值对(如果不需要的话)
        resultMap.remove("class");
        return resultMap;
    }
}

这个方法的返回值类型完全匹配POJO的属性类型,不过要注意它会抛出检查型异常,需要你手动处理或者向上抛出。

3. 自定义Jackson配置(稍复杂但适合纯Jackson场景)

如果不想引入其他依赖,也可以通过配置Jackson的ObjectMapper来保留原始类型。你需要自定义序列化器,让Timestamp这类类型直接以原始对象形式输出:

示例代码:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.sql.Timestamp;

public class PojoMapConverter {
    public static Map<String, Object> pojoToMap(Object pojo) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        // 为Timestamp自定义序列化器,直接返回原始对象
        module.addSerializer(Timestamp.class, new com.fasterxml.jackson.databind.ser.std.StdSerializer<Timestamp>(Timestamp.class) {
            @Override
            public void serialize(Timestamp value, com.fasterxml.jackson.core.JsonGenerator gen, com.fasterxml.jackson.databind.SerializerProvider provider) throws java.io.IOException {
                gen.writeObject(value);
            }
        });
        mapper.registerModule(module);
        
        return mapper.convertValue(pojo, Map.class);
    }
}

不过这种方式需要针对每个特殊类型单独配置,不如前两种工具简便,适合已经重度依赖Jackson且不想加其他依赖的场景。

内容的提问来源于stack exchange,提问作者Sachin C Nambiar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:49:56