2012-05-25 4 views
9

Ich habe eine generische ServiceResponse Klasse wie folgt: XML-Antwort erzeugen, wieWie generiere ich XML-Response aus Klassen mit generischen Vorlagen (<T>) in RESTEasy?

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

} 

Von meinem Resteasy Service, ich will:

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(); 

Aber das ist Fehler zu werfen, da es keine JaxbMarshallWriter für Java ist .util.Liste.

Ich kann Marshall List usinig GenericEntity Klasse.

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

Aber GenericEntity<ServiceResponse<List<Customer>>> funktioniert nicht keine JaxbMarshallWriter für java.util.List sagen.

Gibt es irgendwelche Arbeit um Marshall/Unmarshall-Klassen mit generischen Vorlagen (,)?

+0

vielleicht hilft das? http://stackoverflow.com/questions/5391486/make-a-collection-generic-in-javax-xml-bind – Friso

Antwort

0

Das Problem ist nicht die generische das Problem ist, dass Sie Ihre Liste in einem Objekt verpacken sollten.

Sie können die ResponseData-Klasse mit Anmerkungen versehen, um eine Gruppe von Objekten darzustellen.

0

Eine Lösung, die ich für das gleiche Problem gemacht hatte, war die Erstellung eines neuen Typs, um den generischen Typ List zu simulieren, wie ich getan hatte, erstellte ich einen neuen Typ, den ich Container (zum Beispiel: PersonContainer) nannte was gibt es eine Liste meiner Einheit (Person), die ich anstelle des Listentypen zu verwenden, und es funktioniert sehr gut ...

Hier haben Sie mein Beispiel, wenn es für Sie nützlich sein kann:

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 + '}'; 
    } 
} 

Und das ist der Container AdminContainer:

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

Ich bin mir nicht sicher, ob es einen Unterschied macht, dass Ihre Klasse generische Vorlagen verwendet, aber das ist, wie ich eine XML-Antwort mit Resteasy

Dies ist die Klasse erzeugen würde, die Ihre Service-Antwort

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

Dies ist die Klasse, die Ihre Antwort in XML umwandeln würde. Diese Klasse tut wirklich nicht viel anderes, als XML und JSON aufzunehmen oder zu produzieren, oder was auch immer Sie verwenden. Dann übergibt es die Anfrage an die Klasse, die die eigentliche Arbeit leistet. Dies ist jedoch die Klasse, die Ihre spezifische Frage beantworten würde (glaube ich).

@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); 
     } 
    } 
} 

Dies ist die Klasse, die all die echte Arbeit leistet.

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) 
    } 
} 

Auch ich habe nichts davon getestet. Hoffentlich ist es genug für Sie, um das Muster zu bekommen.

0

Ich weiß viel zu spät zu antworten, aber da es keine Antwort gibt, werde ich versuchen, meine Antwort zu geben hoffe, dass es hilft.

Das Problem ist, wenn Sie eine generische Klasse haben sagen MyClass jaxB excepts T ist entweder mit @ XMLRootElement oder @XMLType annotiert.

In Ihrem Codeszenario hat Ihr Typ T von List List kein @XMLRootElement oder @XMLType, daher wird ein Fehler ausgegeben. Ich denke, die Lösung für die oben genannten Fall ist

wie eine Wrapper-Klasse für Sammlung erstellen
@XMLRootElement 
Class JaxBCollection<T>{ 
    java.util.Collection<T> collection; 
    /* Have getters and setters*/ 
} 

jetzt in Ihrem Code haben so etwas.

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;