web-dev-qa-db-fra.com

Comment ajouter des paramètres à toutes les méthodes de requête HttpClient?

J'écris du code Java qui utilise Apache HttpClient version 4.2.2 pour frapper une API tierce RESTful. Cette API a des méthodes qui utilisent HTTP GET, POST, PUT et DELETE. Il est important de noter que j'utilise une version 4.x.x et non 3.x.x, car l'API a beaucoup changé de 3 à 4. Tous les exemples pertinents que j'ai trouvés étaient pour une version 3.x.x.

Tous les appels d'API nécessitent que vous fournissiez le api_key en tant que paramètre (quelle que soit la méthode utilisée). Cela signifie que peu importe si je fais un GET, POST ou autre, je dois fournir ce api_key pour que l'appel puisse s'authentifier côté serveur.

// Have to figure out a way to get this into my HttpClient call,
// regardless of whether I'm using: HttpGet, HttpPost, HttpPut
// or HttpDelete...
String api_key = "blah-whatever-my-unique-api-key";

J'essaie donc de comprendre comment fournir à HttpClient le api_key quelle que soit ma méthode de requête (qui dépend de la méthode de l'API RESTful que j'essaie d'utiliser). Il semble que HttpGet ne même pas supporte la notion de paramètres, et HttpPost utilise quelque chose appelé HttpParams; mais encore une fois, ces HttpParams ne semblent exister que dans la version 3.x.x de HttpClient.

Je demande donc: Quel est le bon moyen, v4.2.2, d’attacher/ajouter ma chaîne api_key aux quatre :

  • HttpGet
  • HttpPost
  • HttpPut
  • HttpDelete

Merci d'avance.

10
user1768830

Vous pouvez utiliser URIBuilder class pour créer l'URI de la demande pour toutes les méthodes HTTP. Le générateur d'URI fournit la méthode setParameter pour définir le paramètre.

URIBuilder builder = new URIBuilder();
builder.setScheme("http").setHost("www.google.com").setPath("/search")
    .setParameter("q", "httpclient")
    .setParameter("btnG", "Google Search")
    .setParameter("aq", "f")
    .setParameter("oq", "");
URI uri = builder.build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());

La sortie devrait être

http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq= 
18
Raghav Boorgapally

Vous pouvez également utiliser cette approche si vous souhaitez transmettre certains paramètres http et envoyer une demande json:

(Remarque: j'ai ajouté du code supplémentaire au cas où cela aiderait les futurs lecteurs et importateurs à partir des bibliothèques client org.Apache.http)

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();
}
2
Arthur

Une chose importante ici est de dire explicitement les paquets d'Apache que vous devez utiliser, car il existe différentes façons d'implémenter une requête get. 

Par exemple, vous pouvez utiliser Apache Commons ou HttpComponents. Dans cet exemple, je vais utiliser HttpComponents (org.Apache.http.*)

Classe de demande:

package request;

import Java.io.IOException;
import Java.net.URI;
import Java.net.URISyntaxException;

import org.Apache.http.client.methods.CloseableHttpResponse;
import org.Apache.http.client.methods.HttpGet;
import org.Apache.http.client.utils.URIBuilder;
import org.Apache.http.impl.client.CloseableHttpClient;
import org.Apache.http.impl.client.HttpClients;

import Task;

public void sendRequest(Task task) throws URISyntaxException {

    URIBuilder uriBuilder = new URIBuilder();
    uriBuilder.setScheme("http")
            .setHost("localhost")
            .setPort(8080)
            .setPath("/TesteHttpRequest/TesteDoLucas")
            .addParameter("className", task.getClassName())
            .addParameter("dateExecutionBegin", task.getDateExecutionBegin())
            .addParameter("dateExecutionEnd", task.getDateExecutionEnd())
            .addParameter("lastDateExecution", task.getDateLastExecution())
            .addParameter("numberExecutions", Integer.toString(task.getNumberExecutions()))
            .addParameter("idTask", Integer.toString(task.getIdTask()))
            .addParameter("numberExecutions" , Integer.toString(task.getNumberExecutions()));
    URI uri = uriBuilder.build();

    HttpGet getMethod = new HttpGet(uri);

    CloseableHttpClient httpclient = HttpClients.createDefault();

    CloseableHttpResponse response = null;

    try {
        response = httpclient.execute(getMethod);
    } catch (IOException e) {
        //handle this IOException properly in the future
    } catch (Exception e) {
        //handle this IOException properly in the future
    }
}

J'utilise Tomcat v7.0 Server, puis la classe ci-dessus reçoit une tâche et l'envoie à un servlet spécifique dans le lien http: // localhost: 8080/TesteHttpRequest/TesteDoLucas

Mon projet Web dynamique s'appelle TesteHttpRequest et mon servlet y assiste par l'URL / TesteDoLucas.

Classe de tâche:

package bean;

public class Task {

    private int idTask;
    private String taskDescription;
    private String dateExecutionBegin;
    private String dateExecutionEnd;
    private String dateLastExecution;
    private int numberExecutions;
    private String className;

    public int getIdTask() {
        return idTask;
    }

    public void setIdTask(int idTask) {
        this.idTask = idTask;
    }

    public String getTaskDescription() {
        return taskDescription;
    }

    public void setTaskDescription(String taskDescription) {
        this.taskDescription = taskDescription;
    }

    public String getDateExecutionBegin() {
        return dateExecutionBegin;
    }

    public void setDateExecutionBegin(String dateExecutionBegin) {
        this.dateExecutionBegin = dateExecutionBegin;
    }

    public String getDateExecutionEnd() {
        return dateExecutionEnd;
    }

    public void setDateExecutionEnd(String dateExecutionEnd) {
        this.dateExecutionEnd = dateExecutionEnd;
    }

    public String getDateLastExecution() {
        return dateLastExecution;
    }

    public void setDateLastExecution(String dateLastExecution) {
        this.dateLastExecution = dateLastExecution;
    }

    public int getNumberExecutions() {
        return numberExecutions;
    }

    public void setNumberExecutions(int numberExecutions) {
        this.numberExecutions = numberExecutions;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }
}

Classe de servlet:

package servlet;

import Java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/TesteDoLucas")
public class TesteHttpRequestServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;

     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String query = request.getQueryString();
        System.out.println(query);
     }

     protected void doPost(HttpServletRequest request, HttpServletResponse   response) throws ServletException, IOException {
        doGet(request, response);
        }
    }

Les paramètres de requête envoyés seront affichés sur la console.

className = Java.util.Objects% 3B & dateExecutionBegin = 2016% 2F04% 2F07 + 22% 3A22% 3A22 & dateExecutionEnd = 2016% 2F04% 2F07 + 6% du jour dix

Pour corriger le codage, vous pouvez regarder ici: HttpServletRequest UTF-8 Encoding

0