说明

一次在获取菜单列表的时候,发现response中的数据和preview中的数据不一致,在工程中控制台打印出来的数据也不一致,这真是一个神奇的事

事件如下:
我有一个获取菜单列表的接口,返回的字段中ID为long型的,后台是通过雪花算法生成的
response中的数据,其显示为正常的long型数据
757937410badf5f2604cc6883f4c14af

点击preveiw的时候,预览的数据就发生了变化,所有的ID都变成了同一个
29599127238a02faa88a8039719d8d80

控制台打印返回,输出的内容也和preview中的数据一样
359f8d22c22c7b2a2fd89d454e71a184

这就导致了项目里面的key一致从而遍历报错,而且这ID发生了变化后续的逻辑肯定也不正常了

事故缘由分析

经过在网上搜索资料,得知javascript的long型数据的长度为53位,而后台Java的long的长度为64位,当ID长度超长时JavaScript中会进行截取。
而我项目中采用的雪花算法,long的长度均为64位,因此都会发生截取,所以这样才会得到不一致的数据

解决

关于JavaScript与Java中long的处理方法,一般是序列化返回前端的时候将long转换为string,这样前端就可以正常的处理了,不会发生截取。
因此,后端需要处理ID的类型使得long序列化成string
jankson中,如果只针对单个处理的话,直接在需要的字段上加上@JsonSerialize(using= ToStringSerializer.class)即可,如果全局处理的话需要配置jankson序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class SysMenuApi extends Model<SysMenuApi> {

private static final long serialVersionUID = 1L;

/**
* 主键id
*/
@TableId(value = "id", type = IdType.AUTO)
@JsonSerialize(using= ToStringSerializer.class)
private Long id;

/**
* 请求api名称
*/
@TableField("name")
private String name;

/**
* 请求路径
*/
@TableField("path")
private String path;

/**
* 父id
*/
@TableField("parent_id")
private Long parentId;
}

处理之后就正常返回数据了