Json传输BigDecimal类型数据时候丢失无用0解决方案
json
适用于现代 C++ 的 JSON。
项目地址:https://gitcode.com/gh_mirrors/js/json
免费下载资源
·
前言
在公司某次订单上区块链时候通过http形式传输数据到区块链中心,数据是以Json字符串形式传输,但是区块链中心接收到的数据(BigDecimal类型)丢失了无用的0,导致两边签名校验一直失败。记录该痛点,毕竟当时定位问题就花了近一天时间,比如0.000000数据通过json格式http传输到对方那边就变成了0;100.0000500000,则变成了100.00005。
解决分析
解决方式两个思路:
- 要么在传输前将BigDecimal转换成String类型的数据,因为双引号包裹住的数据一定不会被转换舍弃。
- 要么在传输过程中让http保留。
显然第一种对于我们会更加容易,第二种我也不会。
尝试两种思路
第一种试用注解
由于我的传输字段有七八十个,比较笨的方法我每个BigDecimal上面都试用Json注解( @JsonSerialize(using = JsonMessageSerialize.class))
该注解maven依赖为
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
JsonMessageSerialize为我自定义的一个类
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class JsonMessageSerialize extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal bigDecimal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
if (bigDecimal !=null){
BigDecimal decimal=bigDecimal.setScale(2, RoundingMode.HALF_UP);
jsonGenerator.writeString(decimal.toString());
}else {
jsonGenerator.writeString(String.valueOf((Object) null));
}
}
}
这个时候要注意了,如果想使得注解起作用也必须得试用jackson的序列化方式,比如我的是:
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JsonMapper {
public static String objectToString(Object o){
ObjectMapper mapper=new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
try {
return mapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
这个确实可以解决我的问题,但是我个人比较懒,我不想在七八十个字段里面去找BigDecimal然后一个个加注解。
使用字段过滤器
我项目本身使用的Json序列化方式是fastJson,所以在不引入其他jar的情况下选择这种方式最快捷的。只需要在JSON.toJsonString方法里面加入字段过滤就好了,这个也是我之前没见过的方式。
第一回我使用的是:
public static String objectToJson(final Object o) {
//过滤空的字段,日期格式化为yyyy-MM-dd HH:mm:ss,将BigDecimal转成String
private static final SerializerFeature[] IGNORE_NULL = {
SerializerFeature.WriteDateUseDateFormat
,SerializerFeature.WriteBigDecimalAsPlain};
return JSON.toJSONString(o,IGNORE_NULL);
}
但是很可惜这里并没法儿对BigDecimal
转换,后来查阅资料说是这是fastJson的一个bug
最终我采用了字段过滤:
public static String objectToJson(final Object o) {
return JSON.toJSONString(o,new ValueFilter() {
@Override
public Object process(Object object, String name, Object value) {
if(value instanceof BigDecimal) {
return((BigDecimal)value).toPlainString();
}
if(value instanceof Date) {
return new SimpleDateFormat("yyyy-MM-dd").format(value);
}
return value;
}
});
}
果然行得通这类的转换,也成功将这枚多字段里面的BigDecimal转为了String类型。这里做一个记录点
GitHub 加速计划 / js / json
41.72 K
6.61 K
下载
适用于现代 C++ 的 JSON。
最近提交(Master分支:1 个月前 )
960b763e
3 个月前
8c391e04
6 个月前
更多推荐
已为社区贡献1条内容
所有评论(0)