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

ScalaXB生成Case Class添加JAXB注解及XSD转Java替代SBT库咨询

ScalaXB生成Case Class添加JAXB注解及XSD转Java替代SBT库咨询

问题背景

我目前在用ScalaXB插件把XSD文件转换成Scala case class,转换本身没问题,但现在想给生成的类加上javax.xml.bind.annotation相关注解,用来配合JAXB做XML的序列化和反序列化。不过现在遇到了报错:JAXB提示生成的类没有无参构造函数。如果ScalaXB没法实现这个需求的话,有没有其他还在活跃维护的SBT库可以把XSD转换成Java文件?我之前找到过sbt-xjc,但感觉它已经不怎么更新了。

附一下目前ScalaXB生成的代码示例:

// Generated by scalaxb.
package generated

case class EmployeeType(FirstName: String,
                        LastName: String,
                        Age: Int,
                        Email: String)

还有我用的JAXB反序列化代码:

import javax.xml.bind._
import java.io.StringReader

def unmarshalXML[T](xmlString: String)(implicit tag: reflect.ClassTag[T]): Option[T] = {
  try {
    val context = JAXBContext.newInstance(tag.runtimeClass)
    val unmarshaller = context.createUnmarshaller()
    val instance = unmarshaller.unmarshal(new StringReader(xmlString)).asInstanceOf[T]
    Some(instance)
  } catch {
    case ex: Exception =>
      ex.printStackTrace()
      None
  }
}

报错栈信息:

Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
generated.EmployeeType does not have a no-arg default constructor.
this problem is related to the following location:
at generated.EmployeeType


解决方案

1. 给ScalaXB开启JAXB注解生成配置

其实ScalaXB本身就支持生成JAXB所需的注解和无参构造函数,你只需要在build.sbt里添加对应的配置即可:

scalaxbGenerateJaxbAnnotations := true

开启这个配置后,ScalaXB生成的case class会自动带上@XmlRootElement、@XmlElement等JAXB注解,同时还会生成无参构造函数(这正是JAXB要求的)。生成后的代码会类似这样:

package generated

import javax.xml.bind.annotation._

@XmlRootElement(name = "EmployeeType")
case class EmployeeType(var FirstName: String, var LastName: String, var Age: Int, var Email: String) {
  def this() = this("", "", 0, "")
}

这样你的JAXB反序列化方法就能正常工作了,既不用修改现有代码结构,又满足了JAXB的要求。

2. 替代sbt-xjc的活跃XSD转Java SBT库

如果你确实需要把XSD转换成Java类,推荐使用sbt-jaxb,这是目前维护状态良好的替代方案,配置步骤如下:

首先在project/plugins.sbt中添加插件依赖:

addSbtPlugin("com.github.sbt" % "sbt-jaxb" % "2.0.0")

然后在build.sbt里配置XSD文件的路径和生成规则:

jaxbSettings

// 把JAXB生成的Java类加入编译源
sourceGenerators in Compile += (jaxbGenerate in Compile).taskValue

// 指定XSD文件所在目录
jaxbXsdDir in Compile := file("src/main/xsd")

配置完成后,执行sbt compile,插件就会自动把src/main/xsd下的XSD文件转换成带JAXB注解的Java类,生成的文件会放在target/scala-[版本号]/src_managed/main目录下,这些类会自动参与项目编译,完全满足你的序列化需求。


备注:内容来源于stack exchange,提问作者Prabhat Kashyap

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 11:14:38