javascript 精度丢失导致的问题
项目技术:spring boot + mybatis plus+mysql
问题描述:
使用mybatis plus作数据持久化,id生成机制使用IdWorker(其实就是生成id的雪花算法)。当数据从后台传到前端时该算法生成的id后两位会变为0,
如1031751585908113410会变为1031751585908113400,究其原因是javascript精度不够不能保存64位长整形的数据导致。
解决方案:
由于spring boot 默认采用jackson json 作序列化反序列化器,我们的解决方案就基于jack json
定义序列化器:
public class LongJsonSerializer extends JsonSerializer<Long> { @Override public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException { String text = (value == null ? null : String.valueOf(value)); if (text != null) { gen.writeString(text); } } }
定义反序列化器:
public class LongJsonDeserializer extends JsonDeserializer<Long> { private static final Logger logger = (Logger) LoggerFactory.getLogger(LongJsonDeserializer.class); @Override public Long deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { String value = jsonParser.getText(); try { return value == null ? null : Long.parseLong(value); } catch (NumberFormatException e) { logger.error("解析长整形错误", e); return null; } } }
在bean对象长整形属性上用户注解标注引用序列化器
public class ApiAccount { @JsonSerialize(using = LongJsonSerializer.class) @JsonDeserialize(using = LongJsonDeserializer.class) private Long id; @JsonSerialize(using = LongJsonSerializer.class) @JsonDeserialize(using = LongJsonDeserializer.class) private Long orderId; @JsonSerialize(using = LongJsonSerializer.class) @JsonDeserialize(using = LongJsonDeserializer.class) private Long orgId;
至此,当数据从后端传到前端时长整形会自动转变为字符串,数据从前端传到后端时字符串会自动转变为长整形
另:还有其它方式(通过编写全局转换器,对查询结果中所有的Long都进行转换)尚未研究

浙公网安备 33010602011771号