2012-06-07 18 views
5

Tengo un problema con el cliente de Jersey (1.11) con JSONConfiguration.FEATURE_POJO_MAPPING establecido en verdadero. Mi código de prueba se parece a esto:jersey JAX-RS Cláusula de respuesta del cliente JSON con POJO MAPPING & Jackson

MyFooCollectionWrapper<MyFooDTO> resp 
    = webResource.accept(MediaType.APPLICATION_JSON) 
     .get(new GenericType<MyFooCollectionWrapper<MyFooDTO>>() {}); 

En el servidor:

1) mi web.xml tiene POJO Mapeo establece en true.

2) MyFooDTO es simplemente un POJO que tiene este aspecto:

public class MyFooDTO { 

private long id; 
private String propA; 

pubic long getId() { 
    return id; 
} 
public void setId(long id) { 
    this.id = id; 
} 

pubic String getPropA() { 
    return propA; 
} 
public void setPropA(String propA) { 
    this.propA = propA; 
} 

public MyFooDTO(MyFoo aFoo) { 
    this.id = aFoo.getId(); 
    this.propA = aFoo.getPropA(); 
} 

    public MyFooDTO() {} 

} 

3) MyFooCollectionWrapper se ve así: servidor

public class MyFooCollectionWrapper<T> extends MyFooCollectionWrapperBase { 

    Collection<T> aCollection; 

    public MyFooCollectionWrapper() { 
     super(); 
    } 

    public MyFooCollectionWrapper(boolean isOK, String msg, Collection<T> col) { 
     super(isOK, msg); 
     this.aCollection = col; 
    } 

    public void setCollection(Collection<T> collection) { 
     this.aCollection = collection; 
    } 

    @JsonProperty("values") 
    public Collection<T> getCollection() { 
     return aCollection; 
    } 
} 

public class MyFooCollectionWrapperBase { 

    private boolean isOK; 
    private String message; 

    public MyFooCollectionWrapperBase() { 
     this.message = ""; 
     this.isOK = false; 
    } 

    public MyFooCollectionWrapperBase(boolean ok, String msg) { 
     this.isOK = ok; 
     this.message = msg; 
    } 

    .. standard getter/setters .. 

} 

He verificado tiene ningún problema al crear la respuesta JSON. Puedo recuperar con mi código de cliente Jersey si configuro el tipo de respuesta a Cadena. Cuando uso

MyFooCollectionWrapper<MyFooDTO> resp = webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType<MyFooCollectionWrapper<MyFooDTO>>() {}); 

yo esperaría mapeo POJO que sólo el trabajo (Marshall la respuesta) sin necesidad de un lector cuerpo del mensaje personalizado. Sin embargo, me sale:

Jun 04, 2012 3:02:20 PM com.sun.jersey.api.client.ClientResponse getEntity 
SEVERE: A message body reader for Java class com.foo.MyFooCollectionWrapper, and Java type  com.foo. MyFooCollectionWrapper<com.foo.MyFooDTO>, and MIME media type application/json was not found 
Jun 04, 2012 3:02:20 PM com.sun.jersey.api.client.ClientResponse getEntity 
SEVERE: The registered message body readers compatible with the MIME media type are: 
application/json -> 
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App 
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$App 
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$App 
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App 
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App 
*/* -> 
com.sun.jersey.core.impl.provider.entity.FormProvider 
com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider 
com.sun.jersey.core.impl.provider.entity.StringProvider 
com.sun.jersey.core.impl.provider.entity.ByteArrayProvider 
com.sun.jersey.core.impl.provider.entity.FileProvider 
com.sun.jersey.core.impl.provider.entity.InputStreamProvider 
com.sun.jersey.core.impl.provider.entity.DataSourceProvider 
com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General 
com.sun.jersey.core.impl.provider.entity.ReaderProvider 
com.sun.jersey.core.impl.provider.entity.DocumentProvider 
com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader 
com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader 
com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader 
com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General 
com.sun.jersey.json.impl.provider.entity.JSONArrayProvider$General 
com.sun.jersey.json.impl.provider.entity.JSONObjectProvider$General 
com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General 
com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General 
com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General 
com.sun.jersey.core.impl.provider.entity.EntityHolderReader 
com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General 
com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General 
com.sun.jersey.json.impl.provider.entity.JacksonProviderProxy 
com.sun.jersey.moxy.MoxyMessageBodyWorker 
com.sun.jersey.moxy.MoxyListMessageBodyWorker 


com.sun.jersey.api.client.ClientHandlerException: A message body reader for Java class com.foo.MyFooCollectionWrapper, and Java type com.foo. MyFooCollectionWrapper<com.foo. MyFooDTO>, and MIME media type application/json was not found 
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:550) 
    at com.sun.jersey.api.client.ClientResponse.getEntity(ClientResponse.java:524) 
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:686) 
    at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:74) 
    at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:508) 

La ruta de clase en la prueba lado del cliente incluye:

jersey-test-framework-core-1.11.jar 
jersey-test-framework-embedded-glassfish-1.11.jar 
jersey-test-framework-grizzly-1.11.jar 
jersey-test-framework-http-1.11.jar 
jersey-test-framework-inmemory-1.11.jar 
jackson-core-asl.jar 
jackson-jaxrs.jar 
jackson-xc.jar 
jackson-client.jar 
jersey-client.jar 
jersey-core.jar 
jersey-json.jar 
jettison.jar 

Son mis expectativas mal o me estoy perdiendo algo obvio aquí?

Como nota al margen, si agrego las anotaciones JAXB a mis entidades (@XmlRootElement en MyFooCollectionWrapper y MyFooDTO) usando la misma llamada a webResource get, el cliente no recibe una excepción de lector de cuerpo de mensaje, sin embargo, la respuesta es marshaled de modo que MyFooCollectionWrapper se vea bien pero su colección no contenga un MyFooDTO contiene un documento XML con los valores correctos en los nodos/attrs; en otras palabras, MyFooDTP no se clasifica.

Al configurar java.util.logging para CONFIGAR como se sugirió en una respuesta veo lo siguiente, aunque nada salta a mí. Aquí hay un link a la salida que puse en pastebin debido a la longitud.

Gracias,

-Noé

ACTUALIZACIÓN - RESOLVER

Originalmente mi cliente y configuración del cliente se están creando de este modo:

Client rootClient = new Client(); 
ClientConfig clientConfig = new DefaultClientConfig(); 
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); 
Client client = new Client(rootClient, clientConfig); 

Cuando cambié esto simplemente

ClientConfig clientConfig = new DefaultClientConfig(); 
    clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); 
    Client client = Client.create(clientConfig); 

Las cosas funcionaron. Parece que el cliente raíz anuló el clienteConfig en el nuevo cliente. Parece extraño que cuando se utiliza un constructor que especifica un ClientConfig, ClientConfig quede anulado por la configuración de rootClients.

+0

¿También puede mostrar su JSON? – tomfumb

Respuesta

6

para habilitar la asignación POJO en el lado del cliente, acaba de hacer:

ClientConfig clientConfig = new DefaultClientConfig(); 
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); 
Client client = Client.create(clientConfig); 
+0

Ya estoy haciendo todo eso. Esa es la primera frase de mi pregunta anterior, "Estoy teniendo un problema con el cliente de Jersey (1.11) con JSONConfiguration.FEATURE_POJO_MAPPING establecido en true" se refiere a. – NBW

+0

Este enfoque exacto funciona. Vea mis comentarios enmendados arriba para los detalles de lo que estuvo mal. – NBW

+1

Buena respuesta. Esto es esencial al configurar JerseyTest también; de lo contrario, solo la parte del servidor de un JerseyTest funcionará con POJO y el cliente en su clase de prueba fallará: https://java.net/projects/jersey/lists/users/archive/2011- 07/message/43 – pulkitsinghal

0

Creo que es porque MyFooDTO no tiene un constructor sin argumentos.

Si cambia el nivel java.util.logging hasta CONFIG, debería ver una serie de mensajes adicionales que ayudan a diagnosticar dichos problemas.

+0

Mi código realmente tiene el constructor no arg, pero lo había dejado fuera del ejemplo anterior, así que lo he agregado. Entonces, aunque tiene un no-arg, todavía tengo este problema. – NBW

+0

Agregué la salida CONFIG. Nada salta como el problema. – NBW

0

¿Sabes qué es lo que ME ENCUENTRO más fácil?

MyFooDTO[] resp = webResource.accept(MediaType.APPLICATION_JSON).get(MyFooDTO[].class); 

Al usar un tipo de matriz, el marcador identifica exactamente qué tipo desea extraer y sabe que es una colección. No obtienes toda la funcionalidad de una colección de Legit, pero puedes repetirla y transmitirla inmediatamente.

0

se puede habilitar la asignación POJO en el lado del cliente como se muestra a continuación

  ClientConfig clientConfig = new DefaultClientConfig(); 
      clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); 
      Client client = Client.create(clientConfig); 

      WebResource webResource = client 
        .resource("http://localhost:8080/api/url"); 

      ClientResponse response = webResource.accept("application/json") 
        .get(ClientResponse.class); 

      if (response.getStatus() != 200) { 
       throw new RuntimeException("Failed : HTTP error code : " 
         + response.getStatus()); 
      } 

      POJOObject output = response.getEntity(POJOObject.class); 

en caso de tener lista de objetos en respuesta a continuación, puede hacer esto

  List<POJOObject> pojoList = webResource.get(new GenericType<List<POJOObject>>() { }); 

es necesario utilizar estas dependencias

<dependency> 
     <groupId>com.sun.jersey</groupId> 
     <artifactId>jersey-client</artifactId> 
     <version>1.18.1</version> 
    </dependency> 

    <dependency> 
     <groupId>com.sun.jersey</groupId> 
     <artifactId>jersey-json</artifactId> 
     <version>1.18.1</version> 
    </dependency> 
Cuestiones relacionadas