问题说明:
数据库主键是由 雪花算法 得到的id,长度有 18 ~ 19 位,比如:575373347886465024
现象:一个数据数据库存的是575373347886465024,而前端显示的是575373347886465000,进行id索引的时候发现数据不存在。
通过debug发现,数据在程序内部还是正常的,但是出了接口数据就发生了变化,所以应该是返给前端的时候发生了精度丢失。
查询后发现原因:
当字段实体类为Long类型且值超过前端js显示的长度范围时会导致前端回显错误。
解决方案:
1.给id字段增加注解@JsonSerialize
使用JsonSerialize注解序列化的时候把Long自动转为String(针对单个属性)如下:
代码:
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@ApiModelProperty("订单编号-模糊")
@JsonSerialize(using = ToStringSerializer.class)
private Long orderNumber;
2.全局上解决,解决思路同1,配置全局序列化
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
/**
* JacksonConfig
*
* @author Mrcy
*/
@Configuration
public class JacksonConfig {
@Bean
public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
final ObjectMapper objectMapper = builder.build();
SimpleModule simpleModule = new SimpleModule();
// Long 转为 String 防止 js 丢失精度
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
// 忽略 transient 关键词属性
objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}