user1768830
user1768830

Reputation:

How to add parameters to all HttpClient request methods?

I am writing some Java code that uses Apache HttpClient version 4.2.2 to hit a RESTful 3rd party API. This API has methods that utilize HTTP GET, POST, PUT and DELETE. It's important to note that I'm using a 4.x.x version and not 3.x.x, because the API changed a lot from 3 to 4. All relevant examples I've found have been for a 3.x.x version.

All API calls require you provide the api_key as a parameter (regardles of which method you are using). This means that regardles of whether I'm making a GET, POST or otherwise, I need to provide this api_key in order for the call to authenticate server-side.

// 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";

So I'm trying to figure out how to provide HttpClient with the api_key regardless of my request method (which in turn depends on which RESTful API method I'm trying to hit). It looks like HttpGet doesn't even support the notion of parameters, and HttpPost uses something called HttpParams; but again these HttpParams only seem to exist in 3.x.x version of HttpClient.

So I ask: What is the proper, v4.2.2 way to attach/add my api_key String to all four:

Thanks in advance.

Upvotes: 14

Views: 86210

Answers (3)

Raghav Boorgapally
Raghav Boorgapally

Reputation: 412

You can use URIBuilder class to build the request URI for all the HTTP methods. URI builder provides setParameter method to set the parameter.

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());

The output should be

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

Upvotes: 33

Arthur
Arthur

Reputation: 608

You can also use this approach in case you want to pass some http parameters and send a json request:

(note: I have added in some extra code just incase it helps any other future readers and imports are from org.apache.http client libraries)

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

Upvotes: 6

Lucas Amorim Silva
Lucas Amorim Silva

Reputation: 605

An important thing here is to say explictly the apache's packages you must use, because there are different ways to implement a get request.

For example, you could use Apache Commons or HttpComponents. In this example, I will use HttpComponents (org.apache.http.*)

Request class:

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
    }
}

I'm using Tomcat v7.0 Server, then the class above receives a task and sends it to a specific servlet in the link http://localhost:8080/TesteHttpRequest/TesteDoLucas.

My Dynamic Web project is named TesteHttpRequest and my servlet attends by the url /TesteDoLucas

Task class:

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;
    }
}

Servlet class:

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);
        }
    }

The query parameters sent will be shown at console.

className=java.util.Objects%3B&dateExecutionBegin=2016%2F04%2F07+22%3A22%3A22&dateExecutionEnd=2016%2F04%2F07+06%3A06%3A06&lastDateExecution=2016%2F04%2F07+11%3A11%3A11&numberExecutions=10&idTask=1&numberExecutions=10

To fix the encoding, you can look at here: HttpServletRequest UTF-8 Encoding

Upvotes: 1

Related Questions