Oto mój dylemat:Nie można Marszałek java.lang.String
Mam klasy dto dla Organizowanie iz powrotem do/z XML.
Oto sztuczka: Ze względu na liczbę klas dto nasz projekt dotyczy kolekcji z tagiem liczby mnogiej, postanowiłem stworzyć kolekcję delegatów, która pozwala mi wziąć jedną z tych klas i bez wysiłku zamienić ją w Kolekcja i zyskaj wygodę, jaką z nią masz (iteracja, dodawanie itp.).
W naszym projekcie przeprowadzamy testy marshatorskie w celu usunięcia błędów adnotacji i innych. Poniżej znajduje się mój kod błędu.
Problem: W zależności od użytkownika, który wykonuję ten ładunek, otrzymam poniższy błąd. Gdy obiekt zostanie uncharshaled do xml przy użyciu CXF jako odpowiedź na żądanie usługi sieciowej, nie powiedzie się. Dokładny błąd: com.sun.istack.SAXException2: nie można zebrać typu „java.lang.String” jako element, ponieważ brakuje adnotacji @XmlRootElement
Kiedy to marshaled/konwertowana z JAXB w teście jest w porządku. Kiedy ta sama QuickCollection służy do organizowania w wynikach 3rd stron korzystających RestOperations wiosenne i działa dobrze
śruba umysł: Kiedy usunąć dziedziczenia i zarządzania kolekcją jako prywatny członka to wszystko po prostu działa!
To nie ma sensu dla mnie, ponieważ dosłownie zwracam dokładny typ danych w obu sytuacjach.
Poniżej znajduje się cały odpowiedni kod.
To jest klasa dziedziczonych uczestników.
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;
}
}
Oto dziecko klasy 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 +
'}';
}
}
I to nie działa. Dostaję błąd.
Oto klasa dziecka po usunięciu dziedziczenia i działa !!!
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;
}
}
Dlaczego w ogóle ma znaczenie dziedzictwo?
Nie odkryłem tego, ale mam inne DTO w podobnym układzie (BuddyTypes BuddyType). BuddyType ma 2 członków: Long and String. Oba są opisane jako XmlElement. Ta działa dobrze.
Wygląda na to, że członkowie zestawu tworzącego delegata nie są notowani w moim przypadku dotyczącym problemów i nie wiem, jak opisać członka rodziny. Jako dziedziczona klasa nie ma sensu posiadanie jakiejś domyślnej nazwy/adnotacji. Ale próbowałem tego szaleństwa, a adnotacja jest ignorowana - widziałem adnotacje członków nadrzędne ignorowane wcześniej, więc nie jest to nowe.
Nie wiem, czy to możliwe, ale muszę dodać adnotację do członka rodziny.
Czy widziałeś adnotację 'XmlElementWrapper'? Jeśli dobrze zrozumiem twoje wymagania, to znacznie prostszy sposób na dodanie elementu w liczbie mnogiej. –
Widziałem to, ale wszystko, co widziałem, to "BlahBlahWrapper", kiedy jest używane. Co mnie kupuje? zapoznam się z tym –