我有一个从MOXy的XJC版本生成的JAXB模型。 xjc:superclass
标记用于绑定文件中,因此所有对象都扩展了一个公共类。
package my.package
//Base.java
@XmlTransient
public class Base {
//...
}
//MyTag.java (generated from XJC)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {/*...*/})
@XmlRootElement(name = "myTag")
public class MyTag extends Base {
//...
}
可以更改模型和模式,但我可以更改Base类。
我需要扩展MyTag以及模型中的其他类,因此我可以从Base类中自定义其方法行为。所以我扩展了MyTag和其他需要自定义行为的域类,以及ObjectFactory。这些类存在于单独的Java包中。
package my.extended.package
//MyTagExtended.java
public class MyTagExtended extends MyTag {
//...
}
//CustomObjectFactory.java
public class CustomObjectFactory extends ObjectFactory {
//...
@Override
public MyTagExtended createMyTag() {
return new MyTagExtended();
}
//...
}
申请代码:
package application
//Application.java
System.setProperty("org.eclipse.persistence.moxy.annotation.xml-value-extension", "true");
JAXBContext jc = (JAXBContext) JAXBContext.newInstance(XPSObjectFactory.class);
JAXBUnmarshaller u = jc.createUnmarshaller();
return u.unmarshal(xmlFile);
我遇到的问题是MOXy似乎随机决定是否调用CustomObjectFactory或ObjectFactory的方法。
在CustomObjectFactory类中,如果我只有一个重写方法,则始终调用该方法。但是,当我输入更多时,MOXy似乎随机决定是否调用ObjectFactory的方法或CustomObjectFactory。
当我使用与JDK提供的Oracle JAXB实现相同的设置时,它可以正常工作。始终调用CustomObjectFactory的方法。
是否需要设置配置?如何配置MOXy以始终使用我的CustomObjectFactory方法?
编辑: 为了澄清,这里是我如何使相同的场景与Oracle的JAXB实现一起工作:
JAXBContext jc = JAXBContext.newInstance("my.package");
Unmarshaller u = jc.createUnmarshaller();
u.setProperty("com.sun.xml.internal.bind.ObjectFactory", new CustomObjectFactory());
我试图在MOXy unmarshaller上设置ObjectFactory属性,但它引发了异常。
答案 0 :(得分:0)
我找到了MOXy的解决方法。我在XmlClassExtractor上找到了一些信息,可用于指定要实例化的类。由于我无法修改域对象,因此使用了XML文件。
我保持扩展类相同,但修改了Application.java并编写了binding.xml文件和ClassExtractor:
package application
//Application.java
System.setProperty("org.eclipse.persistence.moxy.annotation.xml-value-extension", "true");
Map<String, Object> properties = new HashMap<String, Object>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "classExtractor.xml");
JAXBContext jc = (JAXBContext) JAXBContextFactory.createContext(new Class[]{CustomObjectFactory.class}, properties);
JAXBUnmarshaller u = jc.createUnmarshaller();
return u.unmarshal(xmlFile);
classExtractor.xml:
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="my.package"
version="2.3">
<java-types>
<java-type name="MyTag">
<xml-class-extractor class="my.extended.package.MyTagClassExtractor"/>
</java-type>
</java-types>
</xml-bindings>
类提取器:
package my.extended.package
//MyTagExtractor.java
public class MyTagExtractor extends ClassExtractor {
@Override
public Class<? extends Base> extractClassFromRow(Record databaseRow, Session session) {
return MyTagExtended.class;
}
}
这似乎有效,但它很古怪,容易出现程序员错误,因为必须编辑多个源文件才能获得所需的功能。 unmarshaller上的Oracle的ObjectFactory属性非常简单和简化。有没有人有更好的答案?