java - 来自 Jackson 的 kotlin 的自定义 json 序列化 java 原语
问题描述
在我的项目中有 java 和 kotlin 模块。在某些 kotlin 模块中,我需要自定义序列化。所有长值都应序列化为字符串。我用杰克逊。
例子:
科特林
data class KotlinRecord(val id: Long)
爪哇
public class JavaRecord {
private Long id;
public Long getId() {
return id;
}
public JavaRecord setId(Long id) {
this.id = id;
return this;
}
}
当在java模块中配置 ObjectMapper并且我像这样序列化值时:
ObjectMapper mapper = new ObjectMapper()
.registerModule(new KotlinModule())
.registerModule(new JavaTimeModule())
.registerModule(
new SimpleModule()
.addSerializer(Long.class, LongToStringJSONSerializer.ofObject())
.addSerializer(long.class, LongToStringJSONSerializer.ofPrimitive())
);
JavaRecord javaRecord = new JavaRecord().setId(Long.MAX_VALUE);
KotlinRecord kotlinRecord = new KotlinRecord(Long.MAX_VALUE);
System.out.println("Java record: " + mapper.writeValueAsString(javaRecord));
System.out.println("Kotlin record: " + mapper.writeValueAsString(kotlinRecord));
我得到以下结果:
Java record: {"id":"9223372036854775807"}
Kotlin record: {"id":"9223372036854775807"}
没关系。这就是我需要的。
但是如果我在kotlin模块中这样做:
val mapper = ObjectMapper()
.registerModule(KotlinModule())
.registerModule(JavaTimeModule())
.registerModule(
SimpleModule()
.addSerializer(Long::class.java, LongToStringJSONSerializer.ofObject())
.addSerializer(Long::class.javaPrimitiveType, LongToStringJSONSerializer.ofPrimitive())
)
val javaRecord = JavaRecord().setId(Long.MAX_VALUE)
val kotlinRecord = KotlinRecord(Long.MAX_VALUE)
println("Java record: ${mapper.writeValueAsString(javaRecord)}")
println("Kotlin record: ${mapper.writeValueAsString(kotlinRecord)}")
我得到:
Java record: {"id":9223372036854775807}
Kotlin record: {"id":"9223372036854775807"}
对于定义为 java 类 long 值的记录没有转换为字符串。
我的自定义序列化程序:
public class LongToStringJSONSerializer extends JsonSerializer<Long> {
private boolean forPrimitive;
private LongToStringJSONSerializer(boolean forPrimitive) {
this.forPrimitive = forPrimitive;
}
@Override
public void serialize(Long longVal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws
IOException {
jsonGenerator.writeObject(longVal == null ? "" : String.valueOf(longVal));
}
@Override
public Class<Long> handledType() {
return forPrimitive ? long.class : Long.class;
}
public static LongToStringJSONSerializer ofPrimitive() {
return new LongToStringJSONSerializer(true);
}
public static LongToStringJSONSerializer ofObject() {
return new LongToStringJSONSerializer(false);
}
}
谁能解释这种行为以及需要做些什么来解决它?谢谢!
解决方案
问题在于错误的序列化类型。
对象映射器应该这样定义:
val mapper = ObjectMapper()
.registerModule(KotlinModule())
.registerModule(JavaTimeModule())
.registerModule(
SimpleModule()
.addSerializer(Long::class.javaPrimitiveType, LongToStringJSONSerializer.ofObject())
.addSerializer(Long::class.javaObjectType, LongToStringJSONSerializer.ofPrimitive())
)
我错过了Long::class.javaObjectType
推荐阅读
- pine-script - 需要帮助在日线图上绘制每月魔术趋势指标
- windows - Powershell 和 IBM/Lotus Domino
- swift - 是否可以使用 Catalyst API 向 Touchbar 添加可滚动的按钮列表?
- reactjs - React 道具加载速度不够快
- node.js - Sequelize:包含查询中的无效值符号(col)
- objective-c - NSString** 作为 swift 函数参数
- javascript - 根据公共对象属性的值将数组中的对象索引按相应顺序排列到两个单独的数组中
- python - 如何加入列表中的特定元组
- python-3.x - 如何让 TQDM 进度条在 KB 和 MB 之间自动更新
- c++ - 在主题二分搜索下的 InterviewBit 问题中,在 C++ 中旋转排序数组中的搜索超过了时间限制