속성 값에 따라 JAXB 빈을 서브 클래스로 언 마샬하고 싶습니다.JAXB 상속 - 어노테이션에서 선언 된 서브 타입에 대한 언 마샬링?
목시는 작업을 수행 할 수 있습니다
@XmlDiscriminatorNode("@type")
public static class ActionDef extends ContainerOfStackableDefs { ... }
@XmlDiscriminatorValue("cli")
public static class CliActionDef extends ActionDef {
/** CLI command. EL. */
@XmlAttribute public String command;
}
는 그러나,
JAXBContext
가 지정된 모든 클래스를 필요로한다. "루트"클래스가 아닌 다른 클래스를 정의하는 것은 불쾌한 일입니다. 내가 좋아하는 뭔가를 기대했다
: 나는 XmlAdapter
의에 들어갈 싶지 않아
@XmlDiscriminatorNode("@type")
@XmlSubClasses({ CliActionDef.class, XsltActionDef.class, ... })
public static class ActionDef extends ContainerOfStackableDefs { ... }
,이 사소한 작업이며 사소한 해결책이 있어야합니다.
스펙 또는 MOXy 확장 프로그램이 있습니까? 루트 클래스에 서브 클래스를 나열하는 데 사용할 수 있습니까?
그렇지 않으면 Jandex를 사용하여 자동으로 하위 클래스를 찾습니다. Afterall는, MOXY 너무 ;-)
업데이트를 그렇게 할 수 있습니다 : 한마디로 Exception : "Missing class indicator field from database row [UnmarshalRecordImpl()]." when unmarshalling XML using EclipseLink JAXB (MOXy)
: 기록을 위해, 나는 여기에 설명되어
Descriptor: XMLDescriptor(org.jboss.loom.migrators._ext.MigratorDefinition$ActionDef --> [])
at org.eclipse.persistence.exceptions.DescriptorException.missingClassIndicatorField(DescriptorException.java:957)
...
을 얻고 있었다하지 마십시오 @XmlDiscriminatorNode("@name")
에있는 이름과 동일한 이름의 속성으로 MOXy를 비 정렬 화하십시오. 그렇다면 @XmlReadOnly
이 있고 수업 요약이 없습니다.
업데이트 : 아직 작동하지 않습니다. 나는 계속 기본 수업을 받는다. JDK의 impl이 아닌 MOXy에서 처리했습니다.
내 코드 :
<action type="xslt" var="addAction" ...>
</action>
<action type="manual">
...
</action>
콩 :
//@XmlRootElement
@XmlDiscriminatorNode("@type")
@XmlSeeAlso({ CliActionDef.class, ModuleActionDef.class, CopyActionDef.class, XsltActionDef.class })
public static class ActionDef extends ContainerOfStackableDefs {
//@XmlAttribute
//@XmlReadOnly
public String typeVal; // Was type, caused an exception.
//public List<PropertyBean> properties;
//@XmlAnyAttribute
public Map<String, String> attribs = new HashMap();
}
@XmlRootElement
@XmlDiscriminatorValue("manual")
public static class ManualActionDef extends ActionDef {
}
public static class FileBasedActionDef extends ActionDef {
/** Path mask. Ant-like wildcards, EL. */
@XmlAttribute public String pathMask;
/** Where to store the result. May be a dir or a file. EL. */
@XmlAttribute public String dest;
}
@XmlRootElement
@XmlDiscriminatorValue("xslt")
public static class XsltActionDef extends FileBasedActionDef {
/** XSLT template path. */
@XmlAttribute public String xslt;
}
문제점은 무엇입니까?
이 업데이트 :
최상위 클래스 ContainerOfStackableDefs
에 @XmlDiscriminatorNode ("@ 유형을") 퍼팅 후, 내가 얻을 :
Exception Description: Missing class for indicator field value [manual] of type [class java.lang.String].
Descriptor: XMLDescriptor(org.jboss.loom.migrators._ext.MigratorDefinition$ActionDef --> [])
at org.eclipse.persistence.exceptions.DescriptorException.missingClassForIndicatorFieldValue(DescriptorException.java:938)
at org.eclipse.persistence.internal.oxm.QNameInheritancePolicy.classFromRow(QNameInheritancePolicy.java:264)
한마디로 : java.lang.String
가 없습니다. : 해결할 수 있습니까?
또한, 나는 간단한 테스트 케이스 생성 :
public class JaxbInheritanceTest {
@Test
public void testUnmarshall() throws JAXBException{
final Unmarshaller marshaller = XmlUtils.createJaxbContext(Root.class).createUnmarshaller();
Root root = (Root) marshaller.unmarshal(new StringReader(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root><sub disc=\"foo\"/><sub disc=\"bar\"/></root>"));
boolean rightClass = (DiscFoo.class.isAssignableFrom(root.subs.get(0).getClass()));
Assert.assertTrue("base elements go into subclasses", rightClass);
rightClass = (DiscBar.class.isAssignableFrom(root.subs.get(1).getClass()));
Assert.assertTrue("base elements go into subclasses", rightClass);
}
@XmlRootElement
public static class Root {
@XmlElement(name = "sub")
List<Base> subs;
}
@XmlDiscriminatorNode("@disc")
@XmlSeeAlso({DiscFoo.class, DiscBar.class})
public static abstract class Base {}
@XmlRootElement @XmlDiscriminatorValue("foo")
public static class DiscFoo {}
@XmlRootElement @XmlDiscriminatorValue("bar")
public static class DiscBar {}
}
을하지만 나를 Base
2 배이 또한 제공합니다. 디버거에서 확인한 MOXy에서 처리합니다.
여기에 무슨 문제가 있습니까?
나는 완전히, 덕분에이 간과! –
@ OndraŽižka - 문제 없습니다. '@ XmlSeeAlso'는 바로이 문제를 해결하기 위해 JAXB 2.1에서 소개되었습니다. –
BTW, Jandex 솔루션을 추가하는 것을 고려해보십시오. 사전에 하위 클래스를 미리 모르는 경우가 있습니까? 예 : 플러그인 등. –