在使用kotlin来开发spring boot项目时候,使用myabtis-plus。如果字段是存的json数组,在转换到json字符串的时候,报错如下:
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:689)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755)
这是因为JacksonTypeHandler将json数组转换为List的时候,其中的对象被转成了LinkedHashMap,在转换成json输出的时候,会出现类型不匹配的问题,java语法下是可以正常输出的,kotlin就不行。加了jackson-kotlin-module也不行。
解决方法就是简单粗暴的,对json数据的字段单独配置typehandler,例如下面的图片列表
@TableName(value = "activity_activity",autoResultMap = true)
data class Activity(
@TableId(type = IdType.AUTO)
var id: Long? = null,
var ownerId: Long? = null,
var title: String? = null,
var description: String? = null,
var coverUrl: String? = null,
@TableField(typeHandler = ActivityImageTypeHandler::class)
var images: MutableList<ActivityImage>? = null,
@TableField(value = "is_deleted")
var deleted: Boolean? = null,
@TableField(fill = FieldFill.INSERT)
var createdAt: Instant? = null,
@TableField(fill = FieldFill.INSERT_UPDATE)
var updatedAt: Instant? = null
)
data class ActivityImage(
var url: String? = null
)
@MappedTypes(MutableList::class)
@MappedJdbcTypes(JdbcType.VARCHAR)
class ActivityImageTypeHandler : AbstractJsonTypeHandler<List<ActivityImage>>() {
override fun parse(json: String): List<ActivityImage> {
return try {
objectMapper.readValue(json, object : TypeReference<List<ActivityImage>>() {})
} catch (e: IOException) {
throw RuntimeException(e)
}
}
override fun toJson(obj: List<ActivityImage>): String {
return try {
objectMapper.writeValueAsString(obj)
} catch (e: JsonProcessingException) {
throw RuntimeException(e)
}
}
companion object {
private val objectMapper = ObjectMapper()
}
}
期望后续官方的优化吧。