2012-08-07 35 views
3

enter code here我拥有客户跨两个接口的属性,如下所示。我有使用子接口ICustomer定义的外部XML绑定。当我将pojo编组为xml时,似乎Moxy忽略了超级界面的属性名字。这是一个错误,还是我需要在xml元数据中明确指定这两个接口中的每一个?Moxy不尊重超级类/接口属性

Base接口

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(); 
} 

元数据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> 

演示代码

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); 

回答

1

由EclipseLink的莫西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()); 
} 
1

这有可能是因为他们不是公众莫西不处理超级接口属性。默认情况下,JAXB的访问器类型设置为PUBLIC_MEMBER。子接口上的属性被处理,因为它们在外部绑定中明确指定,但超级接口上的属性并不是因为它们不是公共的。您可以尝试在包或接口级别(在外部元数据中)指定不同的访问者类型,或者公开接口方法以查看这是否可以解决问题。

更新

在进一步的调查,这确实是一个错误。 EclipseLink不会自动处理父接口,因为它应该如此。临时解决方法是为ICustomer添加'super-type ='IBaseCustomer''到Java类型。

我开了这个bug跟踪问题:https://bugs.eclipse.org/bugs/show_bug.cgi?id=386959

+0

Java接口的成员方法始终是公开。 – 2012-08-08 20:36:20