2012-05-25 15 views
9

mam rodzajowe klasy ServiceResponse następująco:Jak wygenerować odpowiedź XML z klas z szablonami ogólnymi (<T>) w trybie RESTEasy?

@XMLRootElement 
public class ServiceResponse<T> 
{ 
    private T data; 
    private String error; 
    //setters n getters 

} 

Z mojego RESTEasy Service, chcę, aby wygenerować odpowiedzi XML jako:

List<Customer> customers = someDAO.getCustomers(); 
ServiceResponse<List<Customer>> resp = new ServiceResponse<List<Customer>>(); 
resp.setData(customers); 
resp.setError("No Error"); 
return resp; 
or return Response.ok().entity(resp).build(); 

Ale to rzuca błąd, ponieważ nie ma JaxbMarshallWriter Java .util.List.

Mogę polecić List usinig klasa GenericEntity.

GenericEntity<List<Customer>> entity = new GenericEntity<List<Customer>>(customers){}; 
Response.ok(entity).build(); 

Ale GenericEntity<ServiceResponse<List<Customer>>> nie działa mówiąc nie JaxbMarshallWriter dla java.util.List.

Czy są jakieś prace nad klasami marshall/unmarshall z szablonami ogólnymi (,)?

+0

może to pomaga? http://stackoverflow.com/questions/5391486/make-a-collection-generic-in-javax-xml-indle – Friso

Odpowiedz

0

Problem nie jest generyczny generyczny Problem polega na tym, że należy zawinąć listę wewnątrz obiektu.

ServiceResponse<ResponseData<Customer>> resp = new ServiceResponse<ResponseData<Customer>>(); 

Następnie można opisać klasę ResponseData w celu przedstawienia zestawu obiektów.

0

Rozwiązaniem, które zrobiłem dla tego samego problemu, było stworzenie nowego typu symulującego typową Listę List, tak jak to zrobiłem, stworzyłem nowy typ, który nazwałam Kontener (na przykład: PersonContainer) w który znajduje się lista mojego podmiot (osoba), że mogę używać zamiast rodzaju listy, i to działa bardzo dobrze ...

Tu masz mój przykład, jeśli może to być przydatne dla Ciebie:

package com.dosideals.server.beans; 

import java.io.Serializable; 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.xml.bind.annotation.XmlRootElement; 

/** 
* 
* @author LOTFI 
*/ 
@Entity 
@XmlRootElement 
public class Admin implements Serializable { 

    @Id 
    private String login; 
    private String password; 
    private String firstName; 
    private String lastName; 

    public Admin() { 
    } 

    public Admin(String login, String password, String firstName, String lastName) { 
     this.login = login; 
     this.password = password; 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

    public String getLogin() { 
     return login; 
    } 

    public void setLogin(String login) { 
     this.login = login; 
    } 

    public String getPassword() { 
     return password; 
    } 

    public void setPassword(String password) { 
     this.password = password; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (obj == null) { 
      return false; 
     } 
     if (getClass() != obj.getClass()) { 
      return false; 
     } 
     final Admin other = (Admin) obj; 
     if ((this.login == null) ? (other.login != null) : !this.login.equals(other.login)) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 7; 
     hash = 83 * hash + (this.login != null ? this.login.hashCode() : 0); 
     return hash; 
    } 

    @Override 
    public String toString() { 
     return "Admin{" + "login=" + login + ", password=" + password + ", firstName=" + firstName + ", lastName=" + lastName + '}'; 
    } 
} 

A to jest kontener KontenerAdministratora:

package com.dosideals.server.beans.containers; 

import com.dosideals.server.beans.Admin; 
import java.util.List; 
import javax.xml.bind.annotation.XmlRootElement; 

/** 
* 
* @author LOTFI 
*/ 
@XmlRootElement 
public class AdminContainer { 

    private List<Admin> admin; 

    public AdminContainer() { 
    } 

    public AdminContainer(List<Admin> admin) { 
     this.admin = admin; 
    } 

    public List<Admin> getAdmin() { 
     return admin; 
    } 

    public void setAdmin(List<Admin> admin) { 
     this.admin = admin; 
    } 
} 
1

Nie jestem pewien, czy to robi różnicę, że klasa wykorzystuje szablony, generyczne, ale jest to w jaki sposób wygenerować odpowiedź XML za pomocą RESTEasy

Jest to klasa, która będzie posiadać swoją odpowiedź usługa

public class ServiceResponse<T> 
{ 
    private T data; 
    private String error; 
    //setters n getters 
} 

To jest klasa, która faktycznie przekształciłaby twoją odpowiedź w XML. Ta klasa naprawdę nie robi wiele poza przyjmowaniem i produkowaniem XML/JSON lub czegokolwiek, z czego korzystasz. Następnie przekazuje żądanie klasie, która wykonuje prawdziwą pracę. To jednak jest klasa, która odpowie na twoje konkretne pytanie (jak sądzę).

@Path("/myrestservice") 
public class SomeRestService 
{ 
    private SomeCoreService coreService; 
    //getters and setters here 

    @POST 
    @Path("/examples/") 
    @Consumes({MediaType.APPLICATION_XML}) //this consumes XML 
    @Produces({MediaType.APPLICATION_XML}) //this produces XML 
    public ServiceResponse<T> exampleFunction(Request request) 
    { 
     try 
     { 
      //Unwrap the request and take only what you need out 
      //of the request object here 
      return this.coreService.examples(request.getStringFromRequest()); 
     } 
     catch(Exception ex) 
     { 
      return new ServiceResponse<T>(Put response error message here); 
     } 
    } 
} 

To jest klasa, która wykonuje całą prawdziwą pracę.

public class SomeCoreService 
{ 
    public ServiceResponse<T> examples(String stringFromRequest) 
    { 
     //do whatever work you need to do here. 
     return new ServiceResponse<T>(put whatever you need in the service response here) 
    } 
} 

Ponadto, nie przetestowałem żadnego z tego. Mam nadzieję, że wystarczy, aby uzyskać wzór.

0

Znam zbyt późno, by odpowiedzieć, ale ponieważ nie ma głosującej odpowiedzi, postaram się dać odpowiedź, mam nadzieję, że pomoże.

Problem polega na tym, że masz klasę ogólną, na przykład MyClass jaxB, z wyjątkiem T ma adnotację @XMLRootElement lub @XMLType.

W scenariuszu kodu Twój typ T z listy list nie ma żadnego z @XMLRootElement lub @XMLType, więc powoduje błąd. Myślę, że rozwiązaniem dla powyższego przypadku jest utworzyć klasy otoki do odbioru jak

@XMLRootElement 
Class JaxBCollection<T>{ 
    java.util.Collection<T> collection; 
    /* Have getters and setters*/ 
} 

Teraz w kodzie mają coś takiego.

List<Customer> customers = someDAO.getCustomers(); 
JaxBCollection<Customer> jaxBCustomers= new JaxBCollection<Customer>(); 
jaxBCustomers.setCollection(customers); 
ServiceResponse<JaxBCollection<Customer>> resp = new ServiceResponse<JaxBCollection<Customer>>(); 
resp.setData(jaxBCustomers); 
resp.setError("No Error"); 
return resp; 
Powiązane problemy