2011-10-07 11 views
6

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.

+1

Czy widziałeś adnotację 'XmlElementWrapper'? Jeśli dobrze zrozumiem twoje wymagania, to znacznie prostszy sposób na dodanie elementu w liczbie mnogiej. –

+0

Widziałem to, ale wszystko, co widziałem, to "BlahBlahWrapper", kiedy jest używane. Co mnie kupuje? zapoznam się z tym –

Odpowiedz

3

Po wyjęciu z pudełka: wypróbuj bibliotekę Simple XML zamiast JAXB. Moje doświadczenie z tym jest najlepsze.

Powiązane problemy