2011-10-07 228 views
6

这是我的困境:不能元帅java.lang.String

我有一个dto类从XML到来回编组。

这里有一个技巧:由于我们的项目处理的dto类的数量是带有复数外部标记的集合,因此我决定创建一个委托集合,以便我可以将这些类中的一个轻松地转换为一个集合,并获得它的便利(迭代,添加等)。

在我们的项目中,我们有编组测试来消除注释错误等。 以下是我的故障码。

问题: 根据封送,如果我延长这个QuickCollection我得到下面的错误。 当使用CXF将对象解组为x​​ml作为对web服务请求的响应时,它将失败。确切的错误: com.sun.istack.SAXException2:不能编组类型“java.lang.String中”为元素,因为它缺少一个@XmlRootElement注释

当测试真实封/取消封送与JAXB它的罚款。 当同样的QuickCollection用于使用Spring RestOperations来自第三方的结果进行编组和工作正常

头脑螺丝: 当我删除的继承和管理的集合作为这一切只是工作的私有成员!

这使得感不是一个针给我,因为我从字面上返回在这两种情况下的精确数据类型。

以下是所有相关的代码。

这是继承的委托类。

public class QuickCollection<T> implements Collection<T> { 
    // to be set if needed after instantiation. To behave like a normal collection, we set it to something safe 
    protected Collection<T> delegate = Collections.emptySet(); 

    public QuickCollection() { 
    } 

    public QuickCollection(Collection<T> delegate) { 
     this.delegate = delegate; 
    } 

    @Override 
    public int size() { 
     return delegate.size(); 
    } 

    @Override 
    public boolean isEmpty() { 
     return delegate.isEmpty(); 
    } 

    @Override 
    public boolean contains(Object o) { 
     return delegate.contains(o); 
    } 

    @Override 
    public Iterator<T> iterator() { 
     return delegate.iterator(); 
    } 

    @Override 
    public Object[] toArray() { 
     return delegate.toArray(); 
    } 

    @Override 
    public <T> T[] toArray(T[] a) { 
     return delegate.toArray(a); 
    } 

    @Override 
    public boolean add(T t) { 
     return delegate.add(t); 
    } 

    @Override 
    public boolean remove(Object o) { 
     return delegate.remove(o); 
    } 

    @Override 
    public boolean containsAll(Collection<?> c) { 
     return delegate.containsAll(c); 
    } 

    @Override 
    public boolean addAll(Collection<? extends T> c) { 
     return delegate.addAll(c); 
    } 

    @Override 
    public boolean removeAll(Collection<?> c) { 
     return delegate.removeAll(c); 
    } 

    @Override 
    public boolean retainAll(Collection<?> c) { 
     return delegate.retainAll(c); 
    } 

    @Override 
    public void clear() { 
     delegate.clear(); 
    } 

    @Override 
    public String toString() { 
     return "" + delegate.toString(); 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     QuickCollection that = (QuickCollection) o; 

     if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     return delegate != null ? delegate.hashCode() : 0; 
    } 
} 

这里是孩子DTO类

@XmlAccessorType(XmlAccessType.PROPERTY) 
@XmlType(name = "BuddyCodes") 
@XmlRootElement(name = "BuddyCodes") 
public class BuddyCodes extends QuickCollection<String> implements Xml { 

    private Long accountId; 

    private Date expirationDate; 

    public BuddyCodes() { 
     super.delegate = new HashSet<String>(); 
    } 

    public BuddyCodes(Long accountId, Set<String> codes, Date expirationDate) { 
     super(codes); 
     this.accountId = accountId; 
     this.expirationDate = expirationDate; 
     super.delegate = new HashSet<String>(); 

    } 

    public BuddyCodes(Long accountId, Date expirationDate) { 
     this.accountId = accountId; 
     this.expirationDate = expirationDate; 
     super.delegate = new HashSet<String>(); 
    } 

    @Override 
    public String toXml() { 
     String retVal; 
     try { 
      retVal = StringUtils.toXml(this); 
     } 
     catch (JAXBException e) { 
      retVal = e.toString(); 
     } 
     return retVal; 

    } 

    public Long getAccountId() { 
     return accountId; 
    } 

    public void setAccountId(Long accountId) { 
     this.accountId = accountId; 
    } 

    public Set<String> getCodes() { 
     return (Set<String>) super.delegate; 
    } 

    @XmlElement(name = "code") 
    public void setCodes(Set<String> codes) { 
     super.delegate = codes; 
    } 

    public Date getExpirationDate() { 
     return expirationDate; 
    } 

    public void setExpirationDate(Date expirationDate) { 
     this.expirationDate = expirationDate; 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     BuddyCodes that = (BuddyCodes) o; 

     if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) return false; 
     if (delegate != null ? !super.delegate.equals(that.delegate) : that.delegate != null) return false; 
     if (expirationDate != null ? !expirationDate.equals(that.expirationDate) : that.expirationDate != null) 
      return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     int result = accountId != null ? accountId.hashCode() : 0; 
     result = 31 * result + (expirationDate != null ? expirationDate.hashCode() : 0); 
     result = 31 * result + (super.delegate != null ? super.delegate.hashCode() : 0); 
     return result; 
    } 

    @Override 
    public String toString() { 
     return "BuddyCodes{" + 
       "accountId=" + accountId + 
       "codes=" + super.delegate + 
       ", expirationDate=" + expirationDate + 
       '}'; 
    } 
} 

而且这是行不通的。我收到错误。

现在,这里是删除继承后的子类,它的作品!

import javax.xml.bind.JAXBException; 
import javax.xml.bind.annotation.*; 
import java.util.Collection; 
import java.util.Date; 
import java.util.HashSet; 
import java.util.Set; 

/** 
* @author christian.bongiorno 
*   Date: 10/3/11 
*   Time: 6:11 PM 
*/ 
@XmlAccessorType(XmlAccessType.PROPERTY) 
@XmlType(name = "BuddyCodes") 
@XmlRootElement(name = "BuddyCodes") 
public class BuddyCodes implements Xml { 

    private Long accountId; 

    private Date expirationDate; 
    private Set<String> delegate; 
    public BuddyCodes() { 
     delegate = new HashSet<String>(); 
    } 

    public BuddyCodes(Long accountId, Set<String> codes, Date expirationDate) { 
     this.accountId = accountId; 
     this.expirationDate = expirationDate; 
     delegate = new HashSet<String>(); 

    } 

    public BuddyCodes(Long accountId, Date expirationDate) { 
     this.accountId = accountId; 
     this.expirationDate = expirationDate; 
     delegate = new HashSet<String>(); 
    } 

    @Override 
    public String toXml() { 
     String retVal; 
     try { 
      retVal = StringUtils.toXml(this); 
     } 
     catch (JAXBException e) { 
      retVal = e.toString(); 
     } 
     return retVal; 

    } 

    public Long getAccountId() { 
     return accountId; 
    } 

    public void setAccountId(Long accountId) { 
     this.accountId = accountId; 
    } 

    public Set<String> getCodes() { 
     return delegate; 
    } 

    @XmlElement(name = "code") 
    public void setCodes(Set<String> codes) { 
     delegate = codes; 
    } 

    public Date getExpirationDate() { 
     return expirationDate; 
    } 

    public void setExpirationDate(Date expirationDate) { 
     this.expirationDate = expirationDate; 
    } 

    public boolean add(String s) { 
     return delegate.add(s); 
    } 

    public int size() { 
     return delegate.size(); 
    } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     BuddyCodes that = (BuddyCodes) o; 

     if (accountId != null ? !accountId.equals(that.accountId) : that.accountId != null) return false; 
     if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false; 
     if (expirationDate != null ? !expirationDate.equals(that.expirationDate) : that.expirationDate != null) 
      return false; 

     return true; 
    } 

    @Override 
    public int hashCode() { 
     int result = accountId != null ? accountId.hashCode() : 0; 
     result = 31 * result + (expirationDate != null ? expirationDate.hashCode() : 0); 
     result = 31 * result + (delegate != null ? delegate.hashCode() : 0); 
     return result; 
    } 


} 

为什么遗传很重要?

我还没有想通了这一点,但是,我还有一个DTO类似的布局(BuddyTypes BuddyType)。 BuddyType有2个成员:Long和String。两者都被标记为XmlElement。这个工作得很好。

看来,集组成了代表的成员不是在我的问题的情况下注释的问题,我不知道如何注释父成员。作为一个继承的类,具有某种默认名称/注释是没有意义的。但是,我尝试了这种疯狂,注释被忽略 - 我以前忽略过父母注释,所以这不是新的。

我不知道这是否是可能的,但我需要注释父成员。

+1

你见过'XmlElementWrapper'注解吗?如果我正确理解你的要求,那将是一种更简单的方法来添加复数包装元素。 –

+0

我已经看到它,但是我所见过的全部是“BlahBlahWrapper”。它给我买什么?我会仔细看看的 –

回答

3

有点开箱:尽量Simple XML库而不是JAXB。我的经验是最好的。