You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot JaxbContextContainer:Kotlin数据类无参构造函数缺失报错

解决JAXB反序列化Kotlin数据类时的无参构造函数错误

问题原因

JAXB(你使用的是GlassFish的JAXB实现)在反序列化XML对象时,要求目标类必须提供无参默认构造函数。而你定义的Kotlin数据类Rss因为所有属性都在主构造函数中且为非空val,Kotlin编译器只会生成带参数的构造函数,没有无参版本,因此触发IllegalAnnotationsException。

解决方案

以下是几种可行的解决方式,按推荐程度排序:

1. 使用Kotlin no-arg 编译器插件(推荐)

这个插件会自动给指定注解的类生成无参构造函数,无需修改现有数据类代码。

步骤:

  • 在项目构建文件(build.gradle.kts 或 build.gradle)中添加插件:
    // build.gradle.kts
    plugins {
        kotlin("jvm") version "你的Kotlin版本号"
        kotlin("plugin.noarg") version "你的Kotlin版本号"
    }
    
    noArg {
        // 给所有标注了@XmlRootElement的类自动生成无参构造
        annotation("jakarta.xml.bind.annotation.XmlRootElement")
        // 可选:指定包范围,比如只给com.example.rss.model下的类生成
        // packageNames.add("com.example.rss.model")
    }
    
  • 保留原数据类代码不变,插件会在编译时自动为Rss类生成无参构造函数,JAXB就能正常反序列化了。

2. 手动给数据类添加无参构造(无插件方案)

修改Rss类的主构造函数,给属性设置默认值,让Kotlin编译器自动生成无参构造:

import jakarta.xml.bind.annotation.XmlAccessType
import jakarta.xml.bind.annotation.XmlAccessorType
import jakarta.xml.bind.annotation.XmlElement
import jakarta.xml.bind.annotation.XmlRootElement

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
data class Rss(
    @field:XmlElement
    val channel: Channel? = null // 设为可空并赋予默认值null
)

如果channel不能为null,可以考虑使用lateinit var(注意只能用于var):

@XmlRootElement
@XmlAccessorType(XmlAccessType.NONE)
data class Rss() { // 无参主构造
    @field:XmlElement
    lateinit var channel: Channel
}

这种方式需要注意lateinit变量必须在使用前被初始化,JAXB反序列化时会通过反射设置值,因此可以正常工作,但data类的equals/hashCode等方法逻辑会受主构造无参的影响,需按需选择。

内容的提问来源于stack exchange,提问作者pixel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:30:56