J'utilise un service Web RESTfull avec cette méthode:
@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String str1, String str2){
System.out.println("value 1 = " + str1);
System.out.println("value 2 = " + str2);
}
Dans mon Android, je souhaite appeler cette méthode. Comment puis-je attribuer les valeurs correctes aux paramètres à l'aide de org.Apache.http.client.methods.HttpPost;
J'ai remarqué que je pouvais utiliser l'annotation @HeaderParam et simplement ajouter des en-têtes à l'objet HttpPost. C'est la bonne route? Le faire comme:
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("str1", "a value");
httpPost.setHeader("str2", "another value");
L'utilisation de la méthode setEntity sur httpPost ne fonctionnera pas. Il définit uniquement le paramètre str1 avec la chaîne json. En l'utilisant comme:
JSONObject json = new JSONObject();
json.put("str1", "a value");
json.put("str2", "another value");
HttpEntity e = new StringEntity(json.toString());
httpPost.setEntity(e);
//server output: value 1 = {"str1":"a value","str2":"another value"}
Pour définir les paramètres de votre HttpPostRequest
, vous pouvez utiliser BasicNameValuePair
, comme ceci:
HttpClient httpclient;
HttpPost httppost;
ArrayList<NameValuePair> postParameters;
httpclient = new DefaultHttpClient();
httppost = new HttpPost("your login link");
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("param1", "param1_value"));
postParameters.add(new BasicNameValuePair("param2", "param2_value"));
httpPost.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8"));
HttpResponse response = httpclient.execute(httpPost);
Vous pouvez également utiliser cette approche si vous souhaitez transmettre des paramètres http et envoyer une demande json:
(note: j'ai ajouté du code supplémentaire juste au cas où cela aiderait les futurs lecteurs)
public void postJsonWithHttpParams() throws URISyntaxException, UnsupportedEncodingException, IOException {
//add the http parameters you wish to pass
List<NameValuePair> postParameters = new ArrayList<>();
postParameters.add(new BasicNameValuePair("param1", "param1_value"));
postParameters.add(new BasicNameValuePair("param2", "param2_value"));
//Build the server URI together with the parameters you wish to pass
URIBuilder uriBuilder = new URIBuilder("http://google.ug");
uriBuilder.addParameters(postParameters);
HttpPost postRequest = new HttpPost(uriBuilder.build());
postRequest.setHeader("Content-Type", "application/json");
//this is your JSON string you are sending as a request
String yourJsonString = "{\"str1\":\"a value\",\"str2\":\"another value\"} ";
//pass the json string request in the entity
HttpEntity entity = new ByteArrayEntity(yourJsonString.getBytes("UTF-8"));
postRequest.setEntity(entity);
//create a socketfactory in order to use an http connection manager
PlainConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
Registry<ConnectionSocketFactory> connSocketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", plainSocketFactory)
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(connSocketFactoryRegistry);
connManager.setMaxTotal(20);
connManager.setDefaultMaxPerRoute(20);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setSocketTimeout(HttpClientPool.connTimeout)
.setConnectTimeout(HttpClientPool.connTimeout)
.setConnectionRequestTimeout(HttpClientPool.readTimeout)
.build();
// Build the http client.
CloseableHttpClient httpclient = HttpClients.custom()
.setConnectionManager(connManager)
.setDefaultRequestConfig(defaultRequestConfig)
.build();
CloseableHttpResponse response = httpclient.execute(postRequest);
//Read the response
String responseString = "";
int statusCode = response.getStatusLine().getStatusCode();
String message = response.getStatusLine().getReasonPhrase();
HttpEntity responseHttpEntity = response.getEntity();
InputStream content = responseHttpEntity.getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String line;
while ((line = buffer.readLine()) != null) {
responseString += line;
}
//release all resources held by the responseHttpEntity
EntityUtils.consume(responseHttpEntity);
//close the stream
response.close();
// Close the connection manager.
connManager.close();
}
En règle générale, un HTTP POST suppose que le contenu du corps contient une série de paires clé/valeur créées (le plus souvent) par un formulaire du côté HTML. Vous ne définissez pas les valeurs. utiliser setHeader, car cela ne les placera pas dans le corps du contenu.
Donc, avec votre deuxième test, le problème que vous avez ici est que votre client ne crée pas plusieurs paires clé/valeur, il en a seulement créé une et cela a été mappé par défaut au premier argument de votre méthode.
Vous pouvez utiliser plusieurs options. Tout d'abord, vous pouvez modifier votre méthode pour n'accepter qu'un seul paramètre d'entrée, puis transmettre une chaîne JSON comme vous le feriez lors de votre deuxième test. Une fois à l'intérieur de la méthode, vous analysez ensuite la chaîne JSON dans un objet permettant l'accès aux champs.
Une autre option consiste à définir une classe qui représente les champs des types d'entrée et d'en faire le seul paramètre d'entrée. Par exemple
class MyInput
{
String str1;
String str2;
public MyInput() { }
// getters, setters
}
@POST
@Consumes({"application/json"})
@Path("create/")
public void create(MyInput in){
System.out.println("value 1 = " + in.getStr1());
System.out.println("value 2 = " + in.getStr2());
}
Selon le framework REST que vous utilisez, vous devez gérer la désérialisation du fichier JSON pour vous.
La dernière option est de construire un corps POST) qui ressemble à:
str1=value1&str2=value2
ajoutez ensuite des annotations supplémentaires à votre méthode de serveur:
public void create(@QueryParam("str1") String str1,
@QueryParam("str2") String str2)
@QueryParam ne se soucie pas de savoir si le champ est dans un post de formulaire ou dans l'URL (comme une requête GET).
Si vous souhaitez continuer à utiliser des arguments individuels sur l'entrée, la clé génère la demande du client afin de fournir des paramètres de requête nommés, soit dans l'URL (pour un GET), soit dans le corps du POST.