【发布时间】:2020-04-01 02:31:42
【问题描述】:
我在 MongoDB 集合 sample 中有以下文档,我想将文档映射回 Kotlin 对象 Sample。
我编写了一个自定义反序列化器来读取 UUID 的二进制值,但它失败了。任何帮助将不胜感激。
db.signals.findOne():
/* 1 */
{
"_id" : ObjectId("5deb5bb749772bab4217199e"),
"name" : "Tom",
"sampleId" : LUUID("6b48b8d3-b64f-cfae-9df1-76dd01933281")
}
Sample.kt
@JsonIgnoreProperties(ignoreUnknown = true)
class Sample @JsonCreator constructor(
@JsonProperty("name")var name: String) {
@JsonProperty("sampleId") val sampleId = UUID.randomUUID();
}
主应用程序。
fun main() {
val config = loadConfig()
val mongoClientURI = config.mongodb;
val mongoClient = MongoClients.create(mongoClientURI);
val db = mongoClient.getDatabase("db");
val objectMapper = ObjectMapper();
val module = SimpleModule();
module.addSerializer(UUID::class.java, mongo.UUIDSerializer)
module.addDeserializer(UUID::class.java, mongo.UUIDDeserializer)
objectMapper.registerModule(module);
val samples = db.getCollection("sample"); //Document{{_id=5deb5bb749772bab4217199e, name=Tom, sampleId=aecf4fb6-d3b8-486b-8132-9301dd76f19d}}
val sampleDoc: Document? = samples.findOne();
println(sampleDoc)
val sample = objectMapper.readValue(sampleDoc?.toJson(), Sample::class.java);
println(sample)
}
异常堆栈跟踪:
线程“主”com.fasterxml.jackson.databind.JsonMappingException 中的异常:当前令牌 (START_OBJECT) 不是 VALUE_STRING 或 VALUE_EMBEDDED_OBJECT,不能作为二进制访问 在 [Source: (String)"{"_id": {"$oid": "5deb5bb749772bab4217199e"}, "name": "Tom", "sampleId": {"$binary": "a0i407ZPz66d8XbdAZMygQ==", "$类型": "03"}}";行:1,列:74](通过引用链:mongodb.Sample["sampleId"]) 在 com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394) 在 com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:353) 在 com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1714) 在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:254) 在 com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:441) 在 com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1287) 在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326) 在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159) 在 com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202) 在 com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205) 在 com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173) 在 mongodb.MongoKt.main(mongo.kt:70) 在 mongodb.MongoKt.main(mongo.kt) 原因:com.fasterxml.jackson.core.JsonParseException:当前令牌(START_OBJECT)不是 VALUE_STRING 或 VALUE_EMBEDDED_OBJECT,不能作为二进制访问 在 [Source: (String)"{"_id": {"$oid": "5deb5bb749772bab4217199e"}, "name": "Tom", "sampleId": {"$binary": "a0i407ZPz66d8XbdAZMygQ==", "$类型": "03"}}";行:1,列:75] 在 com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1840) 在 com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:712) 在 com.fasterxml.jackson.core.json.ReaderBasedJsonParser.getBinaryValue(ReaderBasedJsonParser.java:467) 在 com.fasterxml.jackson.core.JsonParser.getBinaryValue(JsonParser.java:1484) 在 mongodb.mongo$UUIDDeserializer.deserialize(mongo.kt:41) 在 mongodb.mongo$UUIDDeserializer.deserialize(mongo.kt:39) 在 com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138) 在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:252) ... 9 更多
序列化器和反序列化器:
class mongo {
companion object {
fun getBytesFromUUID(uuid: UUID): ByteArray {
val bb: ByteBuffer = ByteBuffer.wrap(ByteArray(16))
bb.putLong(uuid.mostSignificantBits)
bb.putLong(uuid.leastSignificantBits)
return bb.array()
}
fun getUUIDFromBytes(bytes: ByteArray): UUID {
val byteBuffer: ByteBuffer = ByteBuffer.wrap(bytes)
val high: Long = byteBuffer.getLong()
val low: Long = byteBuffer.getLong()
return UUID(high, low)
}
}
object UUIDDeserializer : StdDeserializer<UUID>(UUID::class.java) {
override fun deserialize(parser: JsonParser, deserializer: DeserializationContext): UUID {
val binary: ByteArray = parser.binaryValue
val uuid = getUUIDFromBytes(binary);
return uuid;
}
}
object UUIDSerializer : StdSerializer<UUID>(UUID::class.java) {
override fun serialize(uuid: UUID, jsonGenerator: JsonGenerator, serializerProvider: SerializerProvider) {
jsonGenerator.writeBinary(getBytesFromUUID(uuid))
}
}
}
【问题讨论】:
标签: java mongodb kotlin jackson