在我的程序的一个类中,有一个id
类型的java.util.UUID
字段。将该字段映射并存储在Mongodb中后,它将变为LUUID()
(旧版UUID,子类型0x03)。
我想向ObjectMapper
注册一个自定义的序列化器和反序列化器,以便在存储在DB中时将其转换为UUID
(子类型0x04)对象,同时将java.util.UUID
保留在数据库中。主程序。
我的尝试:
我设法使用自定义序列化程序将UUID
对象写入Mongodb,但是在反序列化时我不必映射回java.util.UUID
我有两个辅助函数,它们可以从java.util.UUID转换为org.bson.types.Binary(存储在mongodb中时可以转换为UUID对象
fun fromStandardBinaryUUID(binary: Binary): UUID
fun toStandardBinaryUUID(uuid: UUID): Binary
Serializer.kt
class UUIDSerializer(t: Class<UUID>): StdSerializer<UUID>(t){
@Throws(IOException::class)
override fun serialize(uuid: UUID,jsonGenerator: JsonGenerator,serializerProvider: SerializerProvider?) {
jsonGenerator.writeObject(toStandardBinaryUUID(uuid))
}
}
Deserializer.kt
class UUIDDeserializer(t: Class<*>): StdDeserializer<UUID>(t) {
constructor() : this(UUID::class.java)
@Throws(IOException::class,JsonProcessingException::class)
override fun deserialize(parser: JsonParser,deserializer: DeserializationContext?): UUID {
val binary = parser.readValueAs(Binary::class.java)
val uuid = fromStandardBinaryUUID(binary);
return uuid; // garbage value,not that actual id.
}
}
注册代码
val uuidSerializer = UUIDSerializer(UUID::class.java)
val uuidDeserializer = UUIDDeserializer(UUID::class.java)
val module = SimpleModule("UUIDSerializer");
module.addDeserializer(UUID::class.java,uuidDeserializer).addSerializer(UUID::class.java,uuidSerializer);
KMongoConfiguration.registerBsonmodule(module)
从StandardBinaryUUID &&到StandardBinaryUUID的说明
fun fromStandardBinaryUUID(binary: Binary): UUID {
var msb: Long = 0
var lsb: Long = 0
val uuidBytes = binary.data
for (i in 8..15) {
lsb = lsb shl 8
lsb = lsb or uuidBytes[i].toLong() and 0xFFL
}
for (i in 0..7) {
msb = msb shl 8
msb = msb or uuidBytes[i].toLong() and 0xFFL
}
return UUID(msb,lsb)
}
fun toStandardBinaryUUID(uuid: UUID): Binary {
var msb = uuid.mostSignificantBits
var lsb = uuid.leastSignificantBits
val uuidBytes = ByteArray(16)
for (i in 15 downTo 8) {
uuidBytes[i] = (lsb and 0xFFL).toByte()
lsb = lsb shr 8
}
for (i in 7 downTo 0) {
uuidBytes[i] = (msb and 0xFFL).toByte()
msb = msb shr 8
}
return Binary(0x04.toByte(),uuidBytes)
}