JAX-RS Jersey Client marshaling réponse JSON avec POJO CARTOGRAPHIE & Jackson
Je vais avoir un peu d'un problème à l'aide de Jersey client (1.11) avec JSONConfiguration.FEATURE_POJO_MAPPING définie sur true. Mon test de code ressemble à ceci:
MyFooCollectionWrapper<MyFooDTO> resp
= webResource.accept(MediaType.APPLICATION_JSON)
.get(new GenericType<MyFooCollectionWrapper<MyFooDTO>>() {});
Sur le serveur:
1) mon web.xml a POJO Cartographie définie sur true.
2) MyFooDTO est tout simplement un POJO qui ressemble à ceci:
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 ressemble à ceci:
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 ..
}
J'ai vérifié le serveur n'a pas de problème de la création de la réponse Json. Je peux les récupérer avec mon Maillot de code client si j'ai défini le type de réponse de la Chaîne. Lorsque j'utilise
MyFooCollectionWrapper<MyFooDTO> resp = webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType<MyFooCollectionWrapper<MyFooDTO>>() {});
Je m'attends à ce POJO cartographie de simplement travailler (marshall la réponse) sans aucun besoin d'un message personnalisé corps reader. Cependant, j'obtiens:
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)
Le chemin de classe sur le côté client de test comprend:
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
Mes attentes sont mal ou alors j'ai loupé quelque chose d'évident ici?
Comme une note de côté, si j'ajoute des annotations JAXB pour mes entités (@XmlRootElement sur MyFooCollectionWrapper et MyFooDTO) à l'aide de la même webResource obtenir de l'appel, le client je n'ai pas un corps de message lecteur exception, cependant, la réponse est assemblée telle que MyFooCollectionWrapper semble ok mais sa collection ne contient pas de MyFooDTO il contient un Document XML avec les valeurs appropriées dans les nœuds/attrs - en d'autres termes MyFooDTP n'a pas obtenir de l'assemblée.
Lors de la configuration de java.util.la journalisation de la configuration comme cela a été suggéré dans une Réponse que j'ai de voir la suite, même si rien ne saute hors de moi. Voici un lien à la sortie que j'ai mis sur pastebin en raison de la longueur.
Merci,
-Noé
MISE À JOUR - RÉSOLU
À l'origine de mon client et de la configuration du client ont été créés comme suit:
Client rootClient = new Client();
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
Client client = new Client(rootClient, clientConfig);
Quand j'ai changé ce simplement
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
Client client = Client.create(clientConfig);
Les choses fonctionnaient. Il semble que le rootClient était primordial de la clientConfig sur le nouveau client. Il semble étrange que lorsque vous utilisez un constructeur qui spécifie un ClientConfig la ClientConfig obtient remplacée par la rootClients config.
OriginalL'auteur NBW | 2012-06-07
Vous devez vous connecter pour publier un commentaire.
Pour permettre POJO de cartographie sur le côté client, il suffit de faire :
Cette approche fonctionne. Voir mon modifiée commentaires ci-dessus pour les détails de ce qui n'allait pas.
La bonne réponse. Cela est essentiel lors de la configuration de JerseyTest trop, sinon seule la partie serveur d'un JerseyTest travaillera avec Pojo et le client dans votre classe de test ne fonctionne pas: java.net/projects/jersey/lists/users/archive/2011-07/message/43
OriginalL'auteur Nicolas Trichet
Je crois que c'est parce
MyFooDTO
n'a pas un no-arg constructeur.Si vous modifiez le java.util.niveau d'enregistrement jusqu'à
CONFIG
, vous devriez voir un certain nombre de messages supplémentaires qui permettent de diagnostiquer de tels problèmes.J'ai ajouté la CONFIG de sortie. Rien de sauts comme étant le problème.
OriginalL'auteur Brett Porter
Vous savez ce que je trouve bien plus facile?
En utilisant un tableau de type le marshaller sait exactement quel type vous voulez tirer dans et sait que c'est une collection. Vous n'obtenez pas toutes les fonctionnalités d'une pièce de théâtre de la collection, mais vous pouvez immédiatement de le parcourir et de le diffuser.
OriginalL'auteur Christian Bongiorno
vous pouvez activer POJO de cartographie sur le côté client comme indiqué ci-dessous
dans le cas où vous avez la liste des objets dans la réponse, alors vous pouvez faire ce
vous avez besoin d'utiliser ces dépendances
OriginalL'auteur Ali