web-dev-qa-db-de.com

Jersey POST Die Methode empfängt Nullwerte als Parameter

Ich entwickle RESTful-Services mit Jersey und es funktioniert hervorragend mit GET-Methoden. Ich kann es jedoch nicht mit POST-Methoden und JSON- oder Text-Parametern zum Laufen bringen. Das ist was ich getan habe:

@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) {
...
}

Ich bekomme nur Nullwerte für alle Parameter. Ich habe versucht, nur einen String als Parameter zu verwenden, und es funktioniert auch nicht ... Ich versuche, auf diese Methoden von IOS aus zuzugreifen, und vielleicht ist das eines der Probleme. Ich habe jedoch mein LAN geschnüffelt und kann die korrekten Parameter im Paketkörper sehen ... ist das richtig? 

Ich habe von XCode verschiedene Textinhalte gesendet als:

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

und:

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

während ich mit @QueryParam und @PathParam ohne Ergebnisse gespielt habe ... immer null ...

Danke für Ihre Hilfe!

11
Kasas

Ein Pfadparameter ist ein Teil der Anforderungs-URL, der einem bestimmten Muster entspricht. Daher gibt es Zeichenbeschränkungen für das, was als Pfadparameter angegeben werden kann. Insbesondere müssen Sonderzeichen URL-codiert sein. Dies gilt auch für jede Art von Anforderung (GET, POST, PUT, DELETE) . 

In der Regel sollten Sie Ihre Pfadparameter auf einfache Werte wie Bezeichner oder Ressourcenendpunkte beschränken. Komplexere Daten sollten über die Anforderungsparameter oder den Anfragetext selbst an den Dienst REST übergeben werden. Hier ist ein gemischter Ansatz, bei dem ein Entitätsbezeichner als Pfadparameter und die Entitätsdaten im Anforderungshauptteil übergeben werden:

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

Im obigen Beispiel wird contactId als Pfadparameter abgerufen und der Kontakt wird automatisch aus dem Anfragetext serialisiert.

Was ich oben beschrieben habe, sindgeneralrules. Was die Besonderheiten Ihres Falles angeht, stelle ich in Ihrem Code fest, dass Sie keine Pfadparameter definieren. Denken Sie daran, dass sie als Teil Ihrer @Path-Annotation definiert werden müssen, bevor sie in Ihrer REST-Methode verbraucht werden:

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

Mit den obigen Änderungen sollten Ihre Parameter nicht mehr als null angezeigt werden, vorausgesetzt, Sie haben die URL auf der Clientseite ordnungsgemäß codiert.


* EDIT *

Aufgrund Ihres Kommentars müssen Sie sich mit der JAX-RS-Spezifikation und den verschiedenen Parametertypen vertraut machen. Ich empfehle, die RESTEasy JAX-RS-Dokumentation durchzulesen . Es enthält einige herstellerspezifische Implementierungsdetails, aber alles in allem ist dies ein hervorragender Leitfaden für JAX-RS.


@PathParam

Zweck: Wird verwendet, um einen Teil der Anforderungs-URL in eine Variable einzufügen. Beachten Sie, dass die URL-Parameter nicht als Teil der URL gelten.

Beispiel: Angesichts der URL http://services.example.com/contacts/20578 kann ich Folgendes definieren:

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

Von dem ich eine @PathParam("id") einspritzen kann.

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

Dies funktioniert für any Art der HTTP-Anfrage (GET, POST, PUT, DELETE)).


@QueryParam

Zweck: Wird verwendet, um einen Teil der Abfragezeichenfolge oder formcodierte Daten in eine Variable einzufügen. Die Abfragezeichenfolge ist der Teil Ihrer URL nach dem ?. Bei formularkodierten Daten handelt es sich um die URL-codierten Name/Wert-Paardaten, die im Hauptteil einer HTTP-Anforderung übergeben werden, wenn der Anforderungstyp application/x-www-form-urlencoded ist. In der Regel werden Abfrageparameter als Teil der URL-Zeichenfolge für GET-Anforderungen und im Anforderungstext für POST-Anforderungen übergeben.

Beispiel: Angesichts der URL http://services.example.com/contacts?group=Business kann ich eine @QueryParam("group") einfügen.

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

Die Verwendung von Abfrageparametern mit einer POST -Anforderung ist untypisch, es ist jedoch möglich, wenn der Anfragetyp Anwendung/x-www-form-urlencoded ist:

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

Dies sind nur Beispiele auf hoher Ebene. Bitte lesen Sie die Dokumentation documentation I, um ein besseres Beispiel dafür zu erhalten, wie jeder Parametertyp funktioniert und wann er welchen verwendet.

23
Perception

Ich habe gerade angefangen, Webservice in Java zu entwickeln, und hatte ein ähnliches Problem mit POST data. . Ich bekam eine sehr einfache Lösung, um die POST -Daten mit @FormParam zu lesen. Eigentlich habe ich die @QueryParam verwendet, um POST -Daten zu lesen. Ich denke, es ist nur für das Lesen der QueryString-Daten mit der GET-Methode gedacht

Eine sehr schöne Dokumentation, die hier gegeben wird. Nachdem ich diesen Artikel gelesen hatte, wurden die meisten meiner Verwirrungen ausgeräumt. http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html_single/index.html

Tipp: Stellen Sie nur sicher, dass Sie bei der Verwendung von @FormParam den Mime-Typ "application/x-www-form-urlencoded" verwenden

6
iNeal

Ich würde dies als Kommentar zu der akzeptierten Antwort posten, aber ich schäme mich nur, das zu tun.

Zusätzlich zu den hervorragenden Ratschlägen oben würde ich hinzufügen, dass Jersey zumindest in Version 2.0.x @FormParam nicht aus der Abfragezeichenfolge abruft. Stattdessen erwartet es, dass es als Name-Wert-Paar in den Anforderungstext aufgenommen wird.

Anstelle von POST http://localhost/app?name=Joe würden Sie beispielsweise POST http://localhost/app Mit dem Textkörper senden:

name=Joe
1
JVW