巨坑系列:Java Bean 转 Map 的坑要注意!

在将Java Bean转换为Map时,常见的坑包括JSON反序列化导致的数据类型丢失(如Long变Integer)和属性名错误解析。例如,fastjson在特定情况下会改变数据类型,而commons-beanutils与cglib的BeanMap虽然保留类型,但属性名可能不准确。解决方案可以参考dubbo的PojoUtils,但需注意特殊属性名可能导致的问题。在使用转换工具时,建议多做验证、阅读源码和调试,以避免陷阱。
摘要由CSDN通过智能技术生成

# 一、背景

有些业务场景下需要将 Java Bean 转成 Map 再使用。

本以为很简单场景,但是坑很多。

# 二、那些坑

2.0 测试对象​​​​

import lombok.Data;import java.util.Date;
@Datapublic class MockObject extends  MockParent{
      private Integer aInteger;    private Long aLong;    private Double aDouble;    private Date aDate;}

父类

import lombok.Data;
@Datapublic class MockParent {
      private Long parent;}

文末福利

2.1 JSON 反序列化了类型丢失

2.1.1 问题复现

将 Java Bean 转 Map 最常见的手段就是使用 JSON 框架,如 fastjson 、 gson、jackson 等。但使用 JSON 将 Java Bean 转 Map 会导致部分数据类型丢失。如使用 fastjson ,当属性为 Long 类型但数字小于 Integer 最大值时,反序列成 Map 之后,将变为 Integer 类型。

maven 依赖:

​​​​​​​

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>fastjson</artifactId>            <version>2.0.8</version>        </dependency>

示例代码:

​​​​​​​

import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.TypeReference;import java.util.Date;import java.util.Map;
public class JsonDemo {
      public static void main(String[] args) {
          MockObject mockObject = new MockObject();        mockObject.setAInteger(1);        mockObject.setALong(2L);        mockObject.setADate(new Date());        mockObject.setADouble(3.4D);        mockObject.setParent(3L);
       String json = JSON.toJSONString(mockObject);               Map<String,Object> map =  JSON.parseObject(json, new TypeReference<Map<String,Object>>(){});
        System.out.println(map);    }}

结果打印:

{"parent":3,"ADouble":3.4,"ALong":2,"AInteger":1,"ADate":1657299916477}

调试截图:

 

通过 Java Visualizer 插件进行可视化查看:

 

2.2.2 问题描述

存在两个问题 

(1) 通过 fastjson 将 Java Bean 转为 Map ,类型会发生转变。如 Long 变成 Integer ,Date 变成 Long, Double 变成 Decimal 类型等。

(2)在某些场景下,Map 的 key 并非和属性名完全对应,像是通过 get set 方法“推断”出来的属性名。

2.2 BeanMap 转换属性名错误

2.2.1 commons-beanutils 的 BeanMap

maven 版本:​​​​​​​

<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils --><dependency>    <groupId>commons-beanutils</groupId>    <artifactId>commons-beanutils</artifactId>    <version>1.9.4</version></dependency>

代码示例:

import org.apache.commons.beanutils.BeanMap;import third.fastjson.MockObject;import java.util.Date;
public class BeanUtilsDemo {
      public static void main(String[] args) {
          MockObject mockObject = new MockObject();        mockObject.setAInteger(1);        mockObject.setALong(2L);        mockObject.setADate(new Date());        mockObject.setADouble(3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值