2012-05-25 9 views
9

tengo una clase ServiceResponse genérica de la siguiente manera:Cómo generar respuestas XML de clases con plantillas genéricas (<T>) en RESTEasy?

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

} 

Desde mi servicio RESTEasy, quiero generar una respuesta XML como:

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

Pero esto es error de tiro ya que no hay JaxbMarshallWriter para Java .util.List.

Puedo ordenar Lista usen la clase GenericEntity.

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

Pero GenericEntity<ServiceResponse<List<Customer>>> no está funcionando decir no JaxbMarshallWriter para java.util.List.

¿Hay algún trabajo para ordenar/deshacer clases con plantillas genéricas (,)?

+0

Quizás esto ayude? http://stackoverflow.com/questions/5391486/make-a-collection-generic-in-javax-xml-bind – Friso

Respuesta

0

El problema no es generic El problema es que debe envolver su lista dentro de un objeto.

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

A continuación, puede anotar la clase ResponseData para representar un conjunto de objetos.

0

Una solución que había hecho para el mismo problema, era la creación de un nuevo tipo para simular el tipo genérico Lista, como lo hice, creé un nuevo tipo que denominé Container (por ejemplo: PersonContainer) en el que hay una lista de mi entidad (persona), que utilizo en lugar del tipo de lista, y funciona muy bien ...

Aquí tienen mi ejemplo si puede ser útil para usted:

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

Y este es el contenedor 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

no estoy seguro de que si se hace una diferencia que su clase utiliza plantillas genéricas, pero esto es como me gustaría generar una respuesta XML utilizando RESTEasy

Ésta es la clase que contenga la respuesta del servicio

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

Esta es la clase que realmente transformaría su respuesta en XML. Esta clase realmente no hace mucho más que capturar y producir XML/JSON o lo que sea que esté usando. A continuación, pasa la solicitud a la clase que hace el trabajo real. Sin embargo, esta es la clase que respondería a tu pregunta específica (creo).

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

Esta es la clase que hace todo el trabajo real.

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

Además, no he probado nada de esto. Con suerte, es suficiente que obtenga el patrón.

0

Sé que es muy tarde para responder, pero como no hay respuesta, intentaré dar mi respuesta con la esperanza de que ayude.

El problema es cuando se tiene una clase genérica que dice MyClass jaxB exceptts T se anota con @XMLRootElement o @XMLType.

En su escenario de código, su tipo T de List List no tiene ninguno de @XMLRootElement o @XMLType, por lo que arroja un error. creo que la solución para el caso anterior es crear una clase de contenedor para la recogida como

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

ahora en su código de tener algo como esto.

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; 
Cuestiones relacionadas