自定义序列化类 将ListLong转为String字符串解决雪花算法id精度丢失问题

自定义序列化类 将ListLong转为String字符串解决雪花算法id精度丢失问题

众所周知,当后端使用Mybatis plus的雪花算法生成id时,会生成一个长度为19位的ID

然后当我们和前端小伙伴对接时,需要转为JSON给前端的js对象接收,此时接收Long类型的是number

然而number类型的长度只有16位!这就出现了精度丢失的问题

前端接收的            ---> 后端实际传的
1297873308628300000 ---> 1297873308628307970 

那怎么办呢?

我们可以配置一个全局序列化以将Long类型在json序列化时转为String给前端

package com.aeotrade.provider.uac.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;


@JsonComponent
public class JacksonConfig {

    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        /**
         * 可配置项:
         * 1.Include.Include.ALWAYS : 默认
         * 2.Include.NON_DEFAULT : 默认值不序列化
         * 3.Include.NON_EMPTY : 属性为 空("") 或者为 NULL 都不序列化
         * 4.Include.NON_NULL : 属性为NULL 不序列化
         **/
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);

        /**
         * 序列化时,将所有的long变成string
         */
        SimpleModule module = new SimpleModule();
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(module);
        return objectMapper;
    }

}

然而这有个问题,他居然会将mybatis中一些分页的参数也转为了String类型,如total:“100”,这就不符合我们的要求了。

最简单的解决方法就是加入一个序列化的注解

@JsonSerialize(using = ToStringSerializer.class)
private Long id;

但是,如果我是List< Long >类型直接加注解会将整个List转为String,得到的结果是[1,2,3],这显然不符合我们想要的1,2,3拼接字符串的结果。

于是我们可以自己自定义一个序列化器

/**
*@Description 自定义序列化器
*/
public class LongArray2StringSerialize extends JsonSerializer<List<Long>> {

    @Override
    public void serialize(List<Long> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        StringBuffer sb = new StringBuffer();
        for (Long str : value) {
            if (sb.length() > 0) {
                sb.append(",");
            }
            sb.append(str);
        }
        gen.writeString(sb.toString());
    }
}

将序列化类指定为我们自定义的

@JsonSerialize(using = LongArray2StringSerialize.class)
private List<Long> ids;

大功告成!

ps:也可以在全局配置的时候,判断属性名后缀来避免序列化不需要的Long类型属性

你可能感兴趣的:(javaWeb,java,javascript,前端,mybatis)