文章
问答
冒泡
kotlin开发spring web项目时mybatis-plus的jacksonTypehandler处理json数组的问题

在使用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()
    }
}
期望后续官方的优化吧。

spring boot
kotlin
Mybatis-plus

关于作者

落雁沙
非典型码农
获得点赞
文章被阅读