前几天做项目,遇到了一个小坑。一个插入数据的操作,在后端应用雪花算法生成了数据的id,插入到库中。id为long类型19位,但是当再次回显给前端时,id值变了。前几位都是一样的,只是在后几位中都变成了零。(由于时间太久,没有保留截图)

在网上差了一下原因和解决办法,在此记录一下,希望对大家有帮助。

我们前后端数据传输,会将返回的数据序列化为json字符串,返回给前端,前端应用js进行数据解析,但是19位的字符串id数据转换成long类型时,由于位数太长丢失了精度,会将后几位用零代替,所以前端显示的就是丢失精度后的数据,当在此传给后端时,后端并不能在数据库中找到相应的数据,导致数据错误或者报错。

其中一种解决办法就是:
1、当我们将数据进行json序列化返回给前端时,先将位数比较多的long类型数据,转换成string类型的数据,然后再封装进json返回。
2、前端用js解析的时候,如果需要可以前端自己转换成数字类型,如果不需要的话,其实string类型也是可以使用的(毕竟id只是作为一个标识,并不作计算使用)。
3、前端再次将数据返回传入到后端的时候,后端需要将string类型的数据,再次转换成Long类型进行后续的数据接收处理操作。

总结一下就是:返回数据前,long转string。接收数据前,string转Long。

那么这时我们就需要使用一个工具类,来做这个转换操作,代码如下:

/*
 * 类名称: LongJsonSerializer
 * 类描述: 向前端返回时将Long转成字符串
*/
public class LongJsonSerializer extends JsonSerializer<Long> {
    @Override
    public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        String text = (value == null ? null : String.valueOf(value));
        if (text != null) {
            jsonGenerator.writeString(text);
        }
    }
}
/*
 * 类名称: LongJsonDeserializer
 * 类描述: 将接收的前端字符串类型转换成Long类型
*/
public class LongJsonDeserializer extends JsonDeserializer<Long> {
    private static final Logger logger = LoggerFactory.getLogger(LongJsonDeserializer.class);
 
    @Override
    public Long deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        String value = jsonParser.getText();
        try {
            return value == null ? null : Long.parseLong(value);
        } catch (NumberFormatException e) {
            logger.error("数据转换异常", e);
            return null;
        }
    }
}

使用:在需要进行转换的字段上面用类注解标识
在这里插入图片描述

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐