1.問題描述
對表的主鍵使用的是雪花策略生成的id,在java中的Long類型的,但在前端精度丟失,現象如下:
{ "id": 1297373218628307972 }
上面假如是后端使用jackson傳遞給前端的,前端接收的id的值卻變成了1297373218628307000。
原因是JavaScript對long類型的解析最多是17位。
2.解決方案
解決辦法就是后端把Long類型轉換成字符串類型傳遞給前端,而前端傳遞給后端后再轉換成Long類型去對應數據庫。
1)新建類,把Long類型轉換成字符串類型
package com.zxh.configure; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; /** * Long 類型字段序列化時轉為字符串,避免js丟失精度 */ public class LongJsonSerializer extends JsonSerializer<Long> { @Override public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException { String text = (value == null ? null : String.valueOf(value)); if (text != null) { jsonGenerator.writeString(text); } } }
2)新建類,把字符串類型轉換成Long類型
package com.zxh.configure; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import lombok.extern.slf4j.Slf4j; import java.io.IOException; /** * 字符串轉為Long */ @Slf4j public class LongJsonDeserializer extends JsonDeserializer<Long> { @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) { log.error("解析長整形錯誤", e); return null; } } }
3)在Long類型的字段上添加注解
package com.zxh.entity; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.ljxx.configure.LongJsonDeserializer; import com.ljxx.configure.LongJsonSerializer; import lombok.Data; import lombok.experimental.Accessors; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable; import java.util.Date; @Data @Accessors(chain = true) public class User implements Serializable { @JsonSerialize(using = LongJsonSerializer.class) @JsonDeserialize(using = LongJsonDeserializer.class) private Long userId; //其他屬性略 }
這樣可以完美解決。
