Loading... # Jackson在Kotlin下全局自定义序列化器Long转String不生效 ## 起因 雪花算法生成的主键传到前段后发生精度丢失,例如后端传入`1397844263642378242`,前端接收后变成`1397844263642378000` 因为Number的精度是16位,而雪花ID是19位 找了网上很多Java下配自定义序列化器的,改成Kotlin语法,如下 ```kotlin @Configuration class JacksonConfig { @Bean fun jacksonObjectMapper(builder: Jackson2ObjectMapperBuilder): ObjectMapper { val objectMapper: ObjectMapper = builder.createXmlMapper(false).build() val simpleModule = SimpleModule() .addSerializer(Long::class.java, ToStringSerializer.instance) .addSerializer(java.lang.Long.TYPE, ToStringSerializer.instance) objectMapper.registerModule(simpleModule) return objectMapper } } ``` 在Kotlin下怎么试都不生效,但是在字段上指定就可以 ```java @JsonSerialize(using=ToStringSerializer.class) val id: Long?; ``` ## 解决 中文互联网找了几遍没找到,去SO一下就找到答案了 [How to use springboot + kotlin + jackson to globally set a custom Long type serializer?](https://stackoverflow.com/questions/76259685/how-to-use-springboot-kotlin-jackson-to-globally-set-a-custom-long-type-seri) 答主是这样解释的:The issue with your code is that the `val Long` and `val Long?` from Kotlin are treated differently. The first will become a `long` whereas the second will become a `Long` (as it can be `null`). 但是这个回答提供的构造Bean的方式我不是很喜欢,因此我又找到了另一个帖子 [Custom json serialization java primitives from kotlin by Jackson](https://stackoverflow.com/questions/56428069/custom-json-serialization-java-primitives-from-kotlin-by-jackson) 最后的解决方案: ```kotlin @Configuration class JacksonConfig { @Bean fun jacksonObjectMapper(builder: Jackson2ObjectMapperBuilder): ObjectMapper { val objectMapper: ObjectMapper = builder.createXmlMapper(false).build() val simpleModule = SimpleModule() .addSerializer(Long::class.javaPrimitiveType, ToStringSerializer.instance) .addSerializer(Long::class.javaObjectType, ToStringSerializer.instance) objectMapper.registerModule(simpleModule) return objectMapper } } ``` 相关: ```xml val <T : Any> KClass<T>.javaPrimitiveType: Class<T>? ``` 返回一个 Java`Class`实例,表示对应于给定`KClass`的基本类型(如果存在)。 ```xml val <T : Any> KClass<T>.javaObjectType: Class<T> ``` 返回对应于给定`KClass`实例的 Java `Class`实例。在原始类型的情况下,它返回相应的包装类。 最后修改:2023 年 07 月 23 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 本作品采用 CC BY-NC-SA 4.0 International License 进行许可。