如何在
中注释list属性case class Foo(list: List[String])
能够使用JAXB序列化吗?
这是我到目前为止所尝试的内容。我使用@XmlElements和@XmlJavaTypeAdapter注释对该属性进行了注释,请参阅类ScalaFoo。但是ScalaFoo序列化失败,但下面有例外,而JavaFoo正常工作。
import java.util
import javax.xml.bind.annotation._
import javax.xml.bind.annotation.adapters._
import ListTest.{xmlElement, xmlElements, xmlTypeAdapter}
import scala.annotation.meta.field
import scala.collection.JavaConverters._
object ListTest extends App {
type xmlElement = XmlElement@field
type xmlElements = XmlElements@field
type xmlTypeAdapter = XmlJavaTypeAdapter@field
import com.sun.jersey.api.json._
val config = JSONConfiguration.natural().rootUnwrapping(true).build()
val context = new JSONJAXBContext(config, classOf[JavaFoo], classOf[ScalaFoo])
val javaFoo = JavaFoo(util.Arrays.asList("a"))
val scalaFoo = ScalaFoo(List("a"))
context.createJSONMarshaller().marshallToJSON(javaFoo, System.out)
context.createJSONMarshaller().marshallToJSON(scalaFoo, System.out)
}
class ListAdapter[A] extends XmlAdapter[java.util.List[A], List[A]] {
def marshal(v: List[A]): util.List[A] = new util.ArrayList(v.asJava)
def unmarshal(v: java.util.List[A]): List[A] = v.asScala.toList
}
@XmlRootElement(name = "foo")
@XmlAccessorType(XmlAccessType.FIELD)
case class JavaFoo(@xmlElements(value = Array(new xmlElement(`type` = classOf[String])))
list: java.util.List[String]) {
private def this() = this(null)
}
@XmlRootElement(name = "foo")
@XmlAccessorType(XmlAccessType.FIELD)
case class ScalaFoo(@xmlTypeAdapter(classOf[ListAdapter[String]])
@xmlElements(value = Array(new xmlElement(`type` = classOf[String])))
list: List[String]) {
private def this() = this(null)
}
例外:
Exception in thread "main" javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.SAXException2: class java.util.ArrayList nor any of its super class is known to this context.
javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.]
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:323)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:177)
at com.sun.jersey.json.impl.JSONMarshallerImpl.marshal(JSONMarshallerImpl.java:94)
at com.sun.jersey.json.impl.BaseJSONMarshaller.marshallToJSON(BaseJSONMarshaller.java:106)
at com.sun.jersey.json.impl.BaseJSONMarshaller.marshallToJSON(BaseJSONMarshaller.java:94)
at ListTest$.delayedEndpoint$ListTest$1(ListTest.scala:26)
at ListTest$delayedInit$body.apply(ListTest.scala:12)
at scala.Function0.apply$mcV$sp(Function0.scala:34)
at scala.Function0.apply$mcV$sp$(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App.$anonfun$main$1$adapted(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:389)
at scala.App.main(App.scala:76)
at scala.App.main$(App.scala:74)
at ListTest$.main(ListTest.scala:12)
at ListTest.main(ListTest.scala)
Caused by: com.sun.istack.SAXException2: class java.util.ArrayList nor any of its super class is known to this context.
javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.
at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:250)
at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:265)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:657)
at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:153)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:597)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:328)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:498)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:320)
... 15 more
Caused by: javax.xml.bind.JAXBException: class java.util.ArrayList nor any of its super class is known to this context.
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:611)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:652)
... 21 more