记一次Spring for Kotlin中JacksonConfig配置Long转String失败

目录

起因

众所周知,浏览器在处理 Long类型(比如雪花算法生成的id)时,往往会出大事情。

浏览器在处理长整型(Long)类型时可能会遇到问题,主要原因是浏览器在处理数字时有限制。一般来说,浏览器的JavaScript引擎使用64位浮点数来表示数字。然而,JavaScript的Number类型只能安全地表示-253到253之间的整数。当超过这个范围时,会有精度丢失的问题。

例如,如果使用雪花算法生成的长整型id超过了JavaScript Number类型的范围,就会出现问题。雪花算法生成的id是一个非常大的数字,如果直接在浏览器中处理,可能会导致精度丢失或溢出。

此外,浏览器在处理长整型时还可能遇到性能问题。处理大数字可能会导致浏览器的运算速度变慢,因为浏览器需要更多的计算资源。

为了避免这些问题,一种常见的做法是将长整型转换为字符串进行处理,而不是直接使用数字类型。这样可以避免精度丢失和性能问题。

在 Spring for Java中,我们可以这样处理:

java 复制代码
@JsonComponent
public class JsonConfig {

    /**
     * 添加 Long 转 json 精度丢失的配置
     */
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(module);
        return objectMapper;
    }
}

但是最近在捣鼓 SpringBoot for kotlin,orm框架用的是 ktorm。此时这个配置突然就失效了

kt 复制代码
// kotlin版本的
@Configuration
class KtormConfiguration {

    @Autowired
    lateinit var dataSource: DataSource

    @Bean
    fun database(): Database {
        return Database.connectWithSpringSupport(dataSource)
    }

    fun ktormModule(): Module {
        return KtormModule()
    }

    @Bean
    fun jacksonObjectMapper(builder: Jackson2ObjectMapperBuilder): ObjectMapper {
        val objectMapper = builder.createXmlMapper(false).build<ObjectMapper>()
        val module = SimpleModule()
        module.addSerializer(Long::class.java, ToStringSerializer.instance)
        module.addSerializer(java.lang.Long.TYPE, ToStringSerializer.instance)
        objectMapper.registerModule(module)
        objectMapper.registerModule(ktormModule())
        return objectMapper
    }
}


而debug看到的返回值却是:

一半是string,一半还是number??

然后我很合理地开始怀疑是不是我这一手 BaseJavaEntity 玩瞎了,我开始变换方式(kotlin有三种方式拓展data class,见:Kotlin 数据类继承:扩展数据类。最后都失败了...

真相

最后发现是:转成功的是Long,没转成功的是Long?...

Long? 表示这值可以为Long也可以为null

那我难道要改成 module.addSerializer(Long?::class.java, ToStringSerializer.instance) ?结果报错了

解决方案

直到我查到了这篇博客:https://cloud.tencent.com/developer/article/2345831

只需要调用 Long::class.javaObjectType,Long::class.javaPrimitiveType即可。

kt 复制代码
@Bean
fun jacksonObjectMapper(builder: Jackson2ObjectMapperBuilder): ObjectMapper {
    val objectMapper = builder.createXmlMapper(false).build<ObjectMapper>()
    val module = SimpleModule()
    module.addSerializer(Long::class.javaObjectType, ToStringSerializer.instance)
    module.addSerializer(Long::class.javaPrimitiveType, ToStringSerializer.instance)
    objectMapper.registerModule(module)
    objectMapper.registerModule(ktormModule())
    return objectMapper
}

搞定(kotlin真的是一门神奇的语言

相关推荐
计算机编程-吉哥6 分钟前
计算机毕业设计 基于 SpringBoot + Vue 的剧本杀系统 Java毕业设计【任务书、开题报告、中期报告、论文、源码】
java·vue.js·spring boot·毕业设计·课程设计·计算机毕业设计选题
code2cat15 分钟前
【随笔】RAG语义缓存:问题很相似,答案就能直接复用吗
java·缓存·知识库·rag
Rain的Java大神之路37 分钟前
面了 50 个候选人,90% 都挂在 LeetCode 3 无重复字符的最长子串:滑动窗口的 5 个致命坑
java·后端·leetcode
西凉的悲伤38 分钟前
Jsoup 库 HTML 解析详解
java·前端·html·jsoup
十碗饭吃不饱1 小时前
Apache POI 踩坑:setFontFamily 二次设置字体不生效、样式残留问题深度解析
java·word·apache
我命由我123451 小时前
6-2.Python 异常处理 - 异常捕获(捕获指定异常、常见异常类型、异常信息)
java·运维·开发语言·python·http·https·java-ee
Flynn Liang1 小时前
保姆级|Spring AI 2.0 第一个 Demo:Spring Boot 4 接入大模型(含国内可用方案 + 完整 pom)
人工智能·spring·ollama·springai·deepseek·springai入门·java接入大模型
Kapaseker1 小时前
AI 会干掉 React Native 吗?
android·kotlin
zaizai10071 小时前
STL深度剖析2
java·c++·算法
周厉1 小时前
WebSocket 使用场景与实现方法:Java + Vue3 全栈实战
java·websocket·vue3·websocket双向通讯