-
Notifications
You must be signed in to change notification settings - Fork 547
Closed
Labels
enhancementNew feature or requestNew feature or request
Milestone
Description
请描述您的需求或者改进建议
背景如下:
1、我们会把java对象通过fastjson转为String然后通过MQ 发送出来,在接收端会再通过fastjson把String转化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转为Double的Converts, 这时就会报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);
}
}
}
}
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request