Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[FEATURE]org.bson.types.Decimal128转Double时会报错 #2558

Closed
ocean23 opened this issue May 10, 2024 · 5 comments
Closed

[FEATURE]org.bson.types.Decimal128转Double时会报错 #2558

ocean23 opened this issue May 10, 2024 · 5 comments
Labels
enhancement New feature or request
Milestone

Comments

@ocean23
Copy link
Contributor

ocean23 commented May 10, 2024

请描述您的需求或者改进建议

背景如下:
1、我们会把java对象通过fastjson转为String然后通过MQ 发送出来,在接收端会再通过fastjsonString转化JSONObject

    public void handleChannel(String data) throws PropertyMapperException {
        JSONObject jsonData = JSON.parseObject(data);
        ViewMO inputMO = jsonData.toJavaObject(ViewMO.class);
        ImportBatchDetailDO task = new ImportBatchDetailDO();
        task.setData(jsonData);
        task.setSyncImportTaskId(inputMO.getId());
        importBatchDetailRepo.save(task);
    }

2、由于fastjson缺省反序列化带小数点的数值类型为BigDecimal,所以上面jsonData这个JSONObject里面的小数都会被转为BigDecimal, 而由于我们的数据库用的是mongodb,所以存储进mongodb时这个BigDecimal又会自动被转为org.bson.types.Decimal128
3、但是当我们从MongoDB读回这个JSONObject对象时,由于java映射这个JSONObject的小数的类型是Double,这时由于fastjson代码里的ObjectReaderProvider.typeConverts并没有把org.bson.types.Decimal128转为DoubleConverts, 这时就会报can not cast to java.lang.Double, from class org.bson.types.Decimal128错误,以下是具体的代码:

@SpringBootTest
public class BigDecimalTest {

    @Autowired
    private ImportBatchDetailRepo importBatchDetailRepo;
    @Test
    public void testBigDecimal() {
        ImportBatchDetailDO importBatchDetailDO = importBatchDetailRepo.findById("64dc97577e47e340a7165e0b");
        JSONObject data = importBatchDetailDO.getData();
        ImportRefinedMO javaObject = data.toJavaObject(ImportRefinedMO.class);

    }
}

@Getter
@Setter
public class ImportBatchDetailDO {

    private String syncImportTaskId;
    private JSONObject data;

}

@Getter
@Setter
public class ImportRefinedMO {

    private Double holidayHour;
}

请描述你建议的实现方案

只要优化TypeUtils.cast这个方法,增加支持从org.bson.types.Decimal128转为Double就可以了,以下是具体的代码可能实现并不是最优美的方式,但是以下这个实现经过我的测试是可以解决我上面这个问题,在TypeUtils类的1525行增加以下代码:

        String objClassName = obj.getClass().getName();
        if (obj instanceof Number && objClassName.equals("org.bson.types.Decimal128") && targetClass == Double.class) {
            ObjectWriter objectWriter = JSONFactory
                    .getDefaultObjectWriterProvider()
                    .getObjectWriter(obj.getClass());
            if (objectWriter instanceof ObjectWriterPrimitiveImpl) {
                Function function = ((ObjectWriterPrimitiveImpl<?>) objectWriter).getFunction();
                if (function != null) {
                    Object apply = function.apply(obj);
                    Function DecimalTypeConvert = provider.getTypeConvert(apply.getClass(), targetClass);
                    if (DecimalTypeConvert != null) {
                        return (T) DecimalTypeConvert.apply(obj);
                    }
                }
            }
        }
@ocean23 ocean23 added the enhancement New feature or request label May 10, 2024
@ocean23
Copy link
Contributor Author

ocean23 commented May 10, 2024

@wenshao 温少, 假如上面优化的代码你看过没问题的话,我就提一个PR

@wenshao
Copy link
Member

wenshao commented May 11, 2024

@ocean23 可以的,你提交吧

@wenshao wenshao added this to the 2.0.50 milestone May 11, 2024
@ocean23
Copy link
Contributor Author

ocean23 commented May 11, 2024

好的,我发PR

ocean23 added a commit to ocean23/fastjson2 that referenced this issue May 11, 2024
ocean23 added a commit to ocean23/fastjson2 that referenced this issue May 11, 2024
@ocean23 ocean23 mentioned this issue May 11, 2024
@ocean23
Copy link
Contributor Author

ocean23 commented May 11, 2024

@wenshao 温少,已发PR

@wenshao
Copy link
Member

wenshao commented May 12, 2024

https://github.com/alibaba/fastjson2/releases/tag/2.0.50
2.0.50已发布,请用新版本

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants