2012-08-07 66 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