Come accedere ai parametri in un metodo POST RESTful

Il mio metodo POST assomiglia a questo:

@POST @Consumes({"application/json"}) @Path("create/") public void create(String param1, String param2){ System.out.println("param1 = " + param1); System.out.println("param2 = " + param2); } 

Quando creo un client Jersey in Netbeans, il metodo che chiama il metodo post è simile al seguente:

 public void create(Object requestEntity){ webResource.path("create").type(MediaType.APPLICATION_JSON).post(requestEntity); } 

Durante l’esecuzione di questo test:

 @Test public void hello(){ String json = "{param1=\"hello\",param2=\"hello2\"}"; this.client.create(json); } 

Fornisce il seguente output nel server:

 INFO: param1 = {param1="hello",param2="hello2"} INFO: param2 = 

Cosa devo cambiare in modo che i parametri diano il valore corretto?

Il @POST metodo @POST dovrebbe accettare un object JSON anziché una stringa. Jersey usa JAXB per supportare gli oggetti JSON di marshalling e unmarshaling (vedere i documenti della jersey per i dettagli ). Crea una class come:

 @XmlRootElement public class MyJaxBean { @XmlElement public String param1; @XmlElement public String param2; } 

Quindi il tuo metodo @POST sarà simile al seguente:

 @POST @Consumes("application/json") @Path("/create") public void create(final MyJaxBean input) { System.out.println("param1 = " + input.param1); System.out.println("param2 = " + input.param2); } 

Questo metodo si aspetta di ricevere oggetti JSON come corpo del POST HTTP. JAX-RS passa il corpo del contenuto del messaggio HTTP come parametro non annotato – input in questo caso. Il messaggio effettivo sarebbe simile a qualcosa:

 POST /create HTTP/1.1 Content-Type: application/json Content-Length: 35 Host: www.example.com {"param1":"hello","param2":"world"} 

L’uso di JSON in questo modo è abbastanza comune per ovvi motivi. Tuttavia, se si sta generando o consumando in qualcosa di diverso da JavaScript, quindi si deve fare attenzione a sfuggire correttamente i dati. In JAX-RS, dovresti usare MessageBodyReader e MessageBodyWriter per implementarlo. Credo che Jersey abbia già implementazioni per i tipi richiesti (ad es., Primitive Java e classi wrapper JAXB) e per JSON. JAX-RS supporta numerosi altri metodi per il trasferimento dei dati. Questi non richiedono la creazione di una nuova class poiché i dati vengono passati utilizzando il passaggio di argomenti semplici.


HTML

I parametri sarebbero annotati usando @FormParam :

 @POST @Path("/create") public void create(@FormParam("param1") String param1, @FormParam("param2") String param2) { ... } 

Il browser codificherà il modulo usando “application / x-www-form-urlencoded” . Il runtime JAX-RS si prenderà cura di decodificare il corpo e passarlo al metodo. Ecco cosa dovresti vedere sul filo:

 POST /create HTTP/1.1 Host: www.example.com Content-Type: application/x-www-form-urlencoded;charset=UTF-8 Content-Length: 25 param1=hello&param2=world 

Il contenuto è codificato URL in questo caso.

Se non conosci i nomi di FormParam puoi fare quanto segue:

 @POST @Consumes("application/x-www-form-urlencoded") @Path("/create") public void create(final MultivaluedMap formParams) { ... } 

Intestazioni HTTP

È ansible utilizzare l’annotazione @HeaderParam se si desidera passare i parametri tramite le intestazioni HTTP:

 @POST @Path("/create") public void create(@HeaderParam("param1") String param1, @HeaderParam("param2") String param2) { ... } 

Ecco come sarà il messaggio HTTP. Nota che questo POST non ha un corpo.

 POST /create HTTP/1.1 Content-Length: 0 Host: www.example.com param1: hello param2: world 

Non userei questo metodo per il passaggio di parametri generalizzati. È molto utile se devi comunque accedere al valore di una particolare intestazione HTTP.


Parametri di query HTTP

Questo metodo viene utilizzato principalmente con HTTP GET ma è ugualmente applicabile ai POST. Utilizza l’annotazione @QueryParam .

 @POST @Path("/create") public void create(@QueryParam("param1") String param1, @QueryParam("param2") String param2) { ... } 

Come la tecnica precedente, il passaggio dei parametri tramite la stringa di query non richiede un corpo del messaggio. Ecco il messaggio HTTP:

 POST /create?param1=hello&param2=world HTTP/1.1 Content-Length: 0 Host: www.example.com 

Devi essere particolarmente attento a codificare correttamente i parametri di query sul lato client. L’utilizzo dei parametri di query può essere problematico a causa delle limitazioni della lunghezza dell’URL imposte da alcuni proxy e dei problemi associati alla codifica.


Parametri del percorso HTTP

I parametri del percorso sono simili ai parametri di query, tranne per il fatto che sono incorporati nel percorso della risorsa HTTP. Questo metodo sembra essere a favore oggi. Vi sono impatti riguardo alla memorizzazione nella cache HTTP poiché il percorso è ciò che definisce realmente la risorsa HTTP. Il codice appare leggermente diverso dagli altri poiché l’annotazione @Path viene modificata e utilizza @PathParam :

 @POST @Path("/create/{param1}/{param2}") public void create(@PathParam("param1") String param1, @PathParam("param2") String param2) { ... } 

Il messaggio è simile alla versione del parametro di query tranne per il fatto che i nomi dei parametri non sono inclusi in nessun punto del messaggio.

 POST /create/hello/world HTTP/1.1 Content-Length: 0 Host: www.example.com 

Questo metodo condivide gli stessi problemi di codifica della versione del parametro di query. I segmenti del percorso sono codificati in modo diverso, quindi devi stare attento anche lì.


Come puoi vedere, ci sono pro e contro per ogni metodo. La scelta viene solitamente decisa dai tuoi clienti. Se stai servendo pagine HTML @FormParam su FORM , quindi usa @FormParam . Se i tuoi client sono basati su JavaScript + HTML5, probabilmente vorrai utilizzare la serializzazione basata su JAXB e gli oggetti JSON. Le implementazioni di MessageBodyReader/Writer dovrebbero occuparsi della fuga necessaria per te in modo che una cosa in meno possa andare storta. Se il tuo client è basato su Java ma non ha un buon processore XML (ad esempio, Android), probabilmente utilizzerei la codifica FORM dal momento che un corpo del contenuto è più facile da generare e codificare correttamente rispetto agli URL. Speriamo che questa voce mini-wiki faccia luce sui vari metodi supportati da JAX-RS.

Nota: nell’interesse della piena divulgazione, non ho ancora utilizzato questa funzionalità di Jersey. Ci siamo messi a fare i conti perché abbiamo un numero di applicazioni JAXB + JAX-RS distribuite e ci stiamo spostando nello spazio client mobile. JSON è molto più adatto a XML su HTML5 o soluzioni basate su jQuery.