これは私のジレンマです。Marshal java.lang.String
私はXMLとの間でマーシャリングするためのdtoクラスを持っています。
私たちのプロジェクトが扱うdtoクラスの数が複数のアウトタグを持つコレクションであるため、私はこれらのクラスのうちの1つを取ることができるデリゲートコレクションを作成することにしました。コレクションに付属している便利さを得ることができます(繰り返し、追加など)。
私たちのプロジェクトでは、注釈エラーなどを洗い流すためのテストをマーシャリングしました。 以下は私のトラブルコードです。
問題: マーシャラによって、このQuickCollectionを拡張すると以下のエラーが発生します。 Webサービス要求への応答としてCXFを使用して、オブジェクトがxmlに非整列化されると失敗します。正確なエラー: com.sun.istack.SAXException2:要素としてのタイプをマーシャリングすることができない「java.lang.Stringで」それはテストでJAXBと/アンマーシャルマーシャリングだとき、それは@XmlRootElement注釈
が不足しているので、それは大丈夫です。この同じQuickCollectionはスプリングRestOperationsを使用してサードパーティからの結果でマーシャリングするために使用され、正常に動作している
心ネジ: 私は、継承を削除し、それがすべてだけの作品のプライベートメンバーとしてコレクションを管理するとき!
これは、両方の状況で文字通り正確なデータ型を返すため、私には意味がありません。
以下はすべての関連コードです。
これはInherited delegateクラスです。ここで
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;
}
}
なぜ継承はどういう意味ですか?
私はこれを理解していませんが、私は同様のレイアウト(BuddyTypes BuddyType)で別のDTOを持っています。 BuddyTypeには、LongとStringの2つのメンバーがあります。両方ともXmlElementとしてマークされます。これはうまく動作します。
デリゲートを構成するセットのメンバーに問題が発生した場合に注釈が付かず、親メンバーに注釈を付ける方法がわかりません。継承されたクラスとして、何らかのデフォルトの名前/注釈を持つことは意味がありません。しかし、私はこの狂気を試して、注釈は無視されました - 私は前に親の注釈が無視されているので、これは新しいものではありません。
可能かどうかわかりませんが、親のメンバーに注釈を付ける必要があります。
あなたは 'XmlElementWrapper'アノテーションを見たことがありますか?あなたの要求を正しく理解すれば、複数のラッパー要素を追加する方がはるかに簡単です。 –
私はそれを見ましたが、私が見たことのあるものはすべて、 "BlahBlahWrapper"が使用されたときです。それは私に何を買うのですか?私はそれを徹底的に調べます –