Jaxb Moxy不尊重超类/接口属性
Jaxb Moxy不尊重超类/接口属性,jaxb,jaxb2,moxy,Jaxb,Jaxb2,Moxy,在此处输入code我拥有跨两个界面的客户属性,如下所示。我使用子接口ICCustomer定义了外部xml绑定。当我将pojo转换为xml时,Moxy似乎忽略了超级接口的属性firstName。这是一个bug还是需要在xml元数据中明确指定这两个接口中的每一个 基本接口 public interface IBaseCustomer { String getFirstName(); void setFirstName(final String firstName); } publ
在此处输入code
我拥有跨两个界面的客户属性,如下所示。我使用子接口ICCustomer定义了外部xml绑定。当我将pojo转换为xml时,Moxy似乎忽略了超级接口的属性firstName。这是一个bug还是需要在xml元数据中明确指定这两个接口中的每一个
基本接口
public interface IBaseCustomer
{
String getFirstName();
void setFirstName(final String firstName);
}
public interface ICustomer extends IBaseCustomer
{
String getLastName();
void setLastName(final String lastName);
Address getAddress();
void setAddress(final Address address);
List<PhoneNumber> getPhoneNumbers();
void setPhoneNumbers(final List<PhoneNumber> phoneNumbers);
void setPrefix(final String prefix);
String getPrefix();
}
Map<String, Object> properties = new HashMap<String, Object>(1);
InputStream resourceAsStream = Demo.class.getResourceAsStream("xml-bindings.xml");
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, resourceAsStream);
JAXBContext jc = JAXBContext.newInstance("blog.bindingfile", ICustomer.class.getClassLoader(), properties);
ICustomer customer = new Customer();
customer.setPrefix("pre");
customer.setFirstName("firstName");
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(customer, System.out);
子接口
public interface IBaseCustomer
{
String getFirstName();
void setFirstName(final String firstName);
}
public interface ICustomer extends IBaseCustomer
{
String getLastName();
void setLastName(final String lastName);
Address getAddress();
void setAddress(final Address address);
List<PhoneNumber> getPhoneNumbers();
void setPhoneNumbers(final List<PhoneNumber> phoneNumbers);
void setPrefix(final String prefix);
String getPrefix();
}
Map<String, Object> properties = new HashMap<String, Object>(1);
InputStream resourceAsStream = Demo.class.getResourceAsStream("xml-bindings.xml");
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, resourceAsStream);
JAXBContext jc = JAXBContext.newInstance("blog.bindingfile", ICustomer.class.getClassLoader(), properties);
ICustomer customer = new Customer();
customer.setPrefix("pre");
customer.setFirstName("firstName");
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(customer, System.out);
公共接口ICustomer扩展IBaseCustomer
{
字符串getLastName();
void setLastName(最终字符串lastName);
地址getAddress();
无效设置地址(最终地址);
列出GetPhoneNumber();
作废设置电话号码(最终列表电话号码);
void setPrefix(最终字符串前缀);
字符串getPrefix();
}
元数据xml
<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" package-name="blog.bindingfile">
<xml-schema namespace="http://www.example.com/customer" element-form-default="QUALIFIED" />
<java-types>
<java-type name="ICustomer">
<xml-root-element name="customer"/>
<xml-type prop-order="firstName lastName address phoneNumbers" />
<java-attributes>
<xml-element java-attribute="firstName" name="first-name" />
<xml-element java-attribute="lastName" name="last-name" />
<xml-element java-attribute="phoneNumbers" name="phone-number" />
</java-attributes>
</java-type>
<java-type name="PhoneNumber">
<java-attributes>
<xml-attribute java-attribute="type" />
<xml-value java-attribute="number" />
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
输出
<customer xmlns="http://www.example.com/customer">
<prefix>pre</prefix>
</customer>
之前
演示代码
public interface IBaseCustomer
{
String getFirstName();
void setFirstName(final String firstName);
}
public interface ICustomer extends IBaseCustomer
{
String getLastName();
void setLastName(final String lastName);
Address getAddress();
void setAddress(final Address address);
List<PhoneNumber> getPhoneNumbers();
void setPhoneNumbers(final List<PhoneNumber> phoneNumbers);
void setPrefix(final String prefix);
String getPrefix();
}
Map<String, Object> properties = new HashMap<String, Object>(1);
InputStream resourceAsStream = Demo.class.getResourceAsStream("xml-bindings.xml");
properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, resourceAsStream);
JAXBContext jc = JAXBContext.newInstance("blog.bindingfile", ICustomer.class.getClassLoader(), properties);
ICustomer customer = new Customer();
customer.setPrefix("pre");
customer.setFirstName("firstName");
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(customer, System.out);
Map属性=新的HashMap(1);
InputStream resourceAsStream=Demo.class.getResourceAsStream(“xml bindings.xml”);
put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY,resourceAsStream);
JAXBContext jc=JAXBContext.newInstance(“blog.bindingfile”,icCustomer.class.getClassLoader(),properties);
ICCustomer客户=新客户();
customer.setPrefix(“pre”);
customer.setFirstName(“firstName”);
Marshaller=jc.createMarshaller();
marshaller.marshall(客户、系统、输出);
MOXy可能没有处理超级接口属性,因为它们不是公共的。默认情况下,JAXB的访问器类型设置为PUBLIC_MEMBER。处理子接口上的属性是因为它们在外部绑定中显式指定,而超级接口上的属性不是因为它们不是公共的。您可以尝试在包或接口级别(在外部元数据中)指定不同的访问器类型,或者公开接口方法,以查看这是否解决了问题
更新
经进一步调查,这确实是一个bug。EclipseLink不会像它应该的那样自动处理父接口。临时解决方法是将“super type=“IBaseCustomer”添加到ICustomer的java类型中
我打开这个bug来跟踪这个问题:已由EclipseLink MOXy V 2.4.1修复 我发现在JavaClassImpl.getSuperClass方法中添加了超级接口支持,如下所示:
public JavaClass getSuperclass() {
if(this.superClassOverride != null) {
return this.superClassOverride;
}
if(jClass.isInterface()) {
Class[] superInterfaces = jClass.getInterfaces();
if(superInterfaces != null) {
if(superInterfaces.length == 1) {
return javaModelImpl.getClass(superInterfaces[0]);
} else {
Class parent = null;
for(Class next:superInterfaces) {
if(!(next.getName().startsWith("java.") || next.getName().startsWith("javax."))) {
if(parent == null) {
parent = next;
} else {
throw JAXBException.invalidInterface(jClass.getName());
}
}
}
return javaModelImpl.getClass(parent);
}
}
}
return javaModelImpl.getClass(jClass.getSuperclass());
}
java接口的成员方法总是公共的。