2014-11-21 38 views
0

我有一個需要mashalling/unmashalling的邏輯。我正在使用jaxws的metro實現。 我使用了Blaise here的建議,它適用於我的對象數據是字符串的場景。對於具有列表作爲我注意到數據,在客戶端(在網絡上)的那些,JAXB產生它自己的自定義ArrayList類即延長定製AbstractList中,如下所示:JAXB地圖錯誤

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "arrayList") 
@XmlSeeAlso({ 
    CustomFieldMap.class 
}) 
public class ArrayList 
    extends AbstractList 
{ 


} 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "abstractList") 
@XmlSeeAlso({ 
    ArrayList.class 
}) 
public abstract class AbstractList 
    extends AbstractCollection 
{ 


} 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "abstractCollection") 
@XmlSeeAlso({ 
    AbstractList.class 
}) 
public abstract class AbstractCollection { 


} 

我認爲上面是有點怪因爲,當客戶需要消耗ArrayList的數據,沒有價值的呈現,因爲它使用的是自定義的ArrayList代替java.util.ArrayList中

我的模型看起來像這樣:

@XmlSeeAlso({ CFMap.class, CField.class, ArrayList.class }) 
public final class MAdapt 
     extends 
     XmlAdapter< CFMap, Map< String, Object >> 
{ 
    @Override 
    public CFMap marshal(Map< String, Object > pCField) 
     throws Exception 
    { 
     CFMap vCFMap = new CFMap(); 

     // ignore custom fields having null values 
     if(pCField == null) 
     { 
     return vCFMap; 
     } 

     for(Entry< String, Object > vEntry : pCField.entrySet()) 
     { 
     CField vCField = new CField(); 
     vCField.key = vEntry.getKey(); 
     vCField.value = vEntry.getValue(); 
     vCFMap.add(vCField); 
     } 

     return vCFMap; 
    } 

    @Override 
    public Map< String, Object > unmarshal(CFMap pCFMap) 
     throws Exception 
    { 
     HashMap< String, Object > vHashMap = new HashMap< String, Object >(); 

     if(pCFMap == null) 
     { 
     return vHashMap; 
     } 

     pCFMap.forEach(p -> vHashMap.put(p.key, p.value)); 

     return vHashMap; 
    } 
} 



@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
@XmlSeeAlso({CField.class, ArrayList.class}) 
public class CFMap extends ArrayList<CField> 
{ 
    private static final long serialVersionUID = 1L; 

    @XmlElement (name = "cField") 
    public List<CField> getCFields() 
    { 
     return this; 
    } 
} 

@XmlRootElement 
@XmlSeeAlso({ MAdapt.class, CFMap.class, ArrayList.class }) 
public class CField 
{ 
    @XmlElement(nillable = true) 
    public String key; 

    @XmlElement(nillable = true) 
    public Object value; 
} 

的用法是:

@XmlRootElement 
public class TestC 
{ 
    .... 
    protected Map< String, Object > csFields; 

    @XmlElement(name = "cfields") 
    @XmlJavaTypeAdapter(MAdapt.class) 
    public Map< String, Object > getCsFields() 
    { 
     return customFields; 
    } 
} 

回答

0

我終於能夠解開這個謎團。

我通過創建一個子類來處理收集類型像這樣修改的適配器:

@XmlType (name = "itemList") 
public static class CType 
{ 
    @XmlElement (name = "item") 
    private Collection<?> items; 
} 

然後數據編排期間執行必要的健全性檢查:

@Override 
public CFMap marshal(Map< String, Object > pCField) 
    throws Exception 
{ 
    ..... 

    for(Entry< String, Object > vEntry : pCField.entrySet()) 
    { 
    ... 
    Object vTempV = vEntry.getValue(); 
    if (vTempV instanceof Collection<?>) 
    { 
     CType wrapper = new CType(); 
     wrapper.collection = (Collection<?>) vTempV; 
     vCustomField.value = wrapper; 
    } 
    else 
    { 
     vCustomField.value = vTempV; 
    } 

    vCFMap.add(vCField); 
    } 

    return vCFMap; 
}