web-dev-qa-db-fra.com

Jersey POST La méthode reçoit des valeurs nulles en tant que paramètres

Je développe des services RESTful avec Jersey et cela fonctionne très bien avec les méthodes GET. Cependant, je ne peux pas le faire fonctionner avec les méthodes POST et les paramètres JSON ou text. Voici ce que j'ai fait:

@Path("/method/")
@POST
@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
@Produces({MediaType.APPLICATION_JSON})
public ResponseObject method(@Context Request request, @PathParam("ob1") Object obj1, @PathParam("obj2") String obj2) {
...
}

Je ne reçois que des valeurs nulles pour tous les paramètres. J'ai essayé d'utiliser uniquement une chaîne en tant que paramètre et cela ne fonctionne pas non plus ... J'essaie d'accéder à ces méthodes à partir de IOS et c'est peut-être l'un des problèmes. Cependant, j'ai détecté mon réseau local et je peux voir les paramètres corrects dans le corps du paquet ... est-ce correct ?? 

J'ai envoyé de XCode différents contenus de corps en tant que:

obj1={"id1": "value1", "id2" : "value2"}&obj2=xxxx

et:

{"id1": "value1", "id2" : "value2"},xxxx

alors que je jouais avec @QueryParam et @PathParam sans résultats ... toujours nuls ...

Merci de votre aide!

11
Kasas

Un paramètre de chemin est une partie de l'URL de la demande correspondant à un modèle particulier. En tant que tel, il existe des limitations de caractères sur ce qui peut être spécifié en tant que paramètre de chemin - en particulier, tous les caractères spéciaux doivent être encodés en URL. Ceci s'applique de la même manière pour tout type de requête (GET, POST, PUT, DELETE).

En règle générale, vous devez limiter vos paramètres de chemin d'accès à des valeurs simples telles que des identifiants ou des noeuds finaux de ressource. Les données plus complexes doivent être transmises au service REST via les paramètres de requête ou le corps de la requête lui-même. Voici une approche mixte qui passe un identifiant d'entité en tant que paramètre de chemin d'accès et les données d'entité dans le corps de la demande:

@Path("/contacts/{id}")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateContact(@PathParam final String contactId, Contact contact) {
}

Dans l'exemple ci-dessus, l'ID de contact est obtenu en tant que paramètre de chemin d'accès et le contact est sérialisé automatiquement à partir du corps de la demande.

Ce que j'ai décrit ci-dessus correspond à règles générales . En ce qui concerne les détails de votre cas, une chose que je remarque dans votre code est que vous ne définissez pas de paramètres de chemin. Rappelez-vous qu'ils doivent être définis dans le cadre de votre annotation @Path avant d'être consommés dans votre méthode REST:

@Path("/method/{obj1}/{obj2}")
public ResponseObject method(@Context Request request, @PathParam("obj1") Object obj1, @PathParam("obj2") String obj2) {
}

Avec les modifications ci-dessus, vos paramètres ne devraient plus apparaître comme étant nuls, en supposant que vous ayez correctement codé l'URL du côté client.


* EDIT *

Sur la base de votre commentaire, je constate que vous devez vous familiariser davantage avec la spécification JAX-RS et les divers types de paramètres. Je recommande de lire RESTEasy Documentation JAX-RS . Certains détails d’implémentation sont spécifiques à chaque fournisseur, mais c’est un excellent guide pour JAX-RS.


@PathParam

Purpose : Utilisé pour injecter une partie de l'URL de la demande dans une variable. Notez que les paramètres d'URL ne sont pas considérés comme faisant partie de l'URL.

Exemple : Étant donné l'URL http://services.example.com/contacts/20578, je peux définir:

@Path("/contacts/{id}")

A partir de laquelle je peux injecter une @PathParam("id").

public Response getContact(@PathParam("id") final String identifier);

Cela fonctionne pour tout type de requête HTTP (GET, POST, PUT, DELETE).


@QueryParam

Purpose : Utilisé pour injecter une partie de la chaîne de requête ou des données codées sous la forme dans une variable. La chaîne de requête est la partie de votre URL après le ?. Les données codées de formulaire sont les données de paire nom/valeur codées en URL transmises dans le corps d'une requête HTTP, lorsque le type de requête est application/x-www-form-urlencoded . Généralement, les paramètres de requête sont transmis dans la chaîne d'URL pour les requêtes GET et dans le corps de requête pour les requêtes POST.

Exemple: étant donné l'URL http://services.example.com/contacts?group=Business , je peux injecter une @QueryParam("group")

public Response getContactsInGroup(@QueryParam("group") final String groupName);

Il est inhabituel d'utiliser des paramètres de requête avec une requête POST, mais il est possible si le type de requête est application/x-www-form-urlencoded :

@POST
@Path("/contacts")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createContact(@QueryParam("contact") final Contact contactData, @QueryParam("metadata") final String metaData);

Ce ne sont que des exemples de haut niveau. Veuillez lire la documentation J'ai lié pour obtenir un meilleur exemple du fonctionnement de chaque type de paramètre et du moment d'utilisation.

23
Perception

Je viens juste de commencer à développer Webservice en Java et je rencontre un même problème avec les données POST . J'ai obtenu une solution très simple pour lire les données POST à l'aide de @FormParam , en fait, j'utilisais le @QueryParam pour lire POST des données, je pense que ce n'est que pour lire les données QueryString à l'aide de la méthode GET

Une très belle documentation donnée ici. Après avoir lu cet article, la plupart de mes confusions ont été effacées . http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html_single/index.html

Conseil: Assurez-vous simplement que vous utilisez le type mime "application/x-www-form-urlencoded" lors de l'utilisation de @FormParam.

6
iNeal

Je posterais cela comme un commentaire sur la réponse acceptée, mais je suis juste timide pour pouvoir le faire.

En plus des excellents conseils ci-dessus, j'ajouterais que, du moins dans la version 2.0.x, Jersey ne tire pas @FormParam de la chaîne de requête. Au lieu de cela, il s'attend à ce qu'il soit inclus en tant que paire nom-valeur dans le corps de la demande.

Par exemple, au lieu de POST http://localhost/app?name=Joe, vous enverriez POST http://localhost/app avec le corps:

name=Joe
1
JVW