Apache HTTP Client Example

Apache HTTP Client Example

It has been quite a while since I last posted on HttpURLConnection class to perform GET and POST request operations from a Java client. If you need a refresher on the common components of the URL is strongly recommended to take a few minutes and visit our other earlier post. In this tutorial, we will learn how to perform similar operations using the Apache HttpClient.

Getting Started

In order to run this tutorial yourself, you will need the following:

Required Libraries

Copy all of the following jars to lib folder ofthe current project then use Java Build Path->Add Jars.

httpclient_jars
commons-cli-1.3.1.jar
commons-codec-1.9.jar
commons-logging-1.2.jar
fluent-hc-4.5.jar
httpclient-4.5.jar
httpclient-cache-4.5.jar
httpclient-win-4.5.jar
httpcore-4.4.1.jar
httpmime-4.5.jar
jna-4.1.0.jar
jna-platform-4.1.0.jar
log4j-1.2.17.jar

Complete Project Overview

I have added the project overview to give you a full view of the structure and show you all files contained in this sample project.

httpclient_proj_struct

Using Apache HttpClient

Now that we have added all of the dependency jar files for our project we can begin using our Apache Http Client application. For the sake of simplicity, I have decided to create one main class called ApacheConnection Class which contains methods executeGet, executePost, executeSSLGet, executeSSLPost and executeSSLGetAllTrusting.

All of the methods perform the same basic operations:

  1. Create an instance of HttpClient using HttpClientBuilder
  2. Create an instance of either HttpGet or HttpPost depending on your desired HTTP request type
  3. Next we use addHeader if header parameters are available
  4. For our executePost method, we create a List of NameValuePair and pass any post parameters here.
  5. We then set up our ResponseHandler to handle data from our HTTP request

The ApacheConnection Class (ApacheConnection.java)

package com.avaldes.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

public class ApacheConnection {
  private static final Logger logger = Logger
      .getLogger(ApacheConnection.class);

  public String executePost(String URLAddress,
      Map<String, String> headerParams,
      List<NameValuePair> postParams) throws MalformedURLException {

    HttpClient client = HttpClientBuilder.create().build();
    HttpPost httpPost = new HttpPost(URLAddress);

    if (headerParams != null) {
      for (String header : headerParams.keySet()) {
        httpPost.addHeader(header, headerParams.get(header));
      }
    }

    // Set UTF-8 character encoding to ensure proper 
    // encoding structure in your posts
    if (postParams != null)
      try {
        httpPost
            .setEntity(new UrlEncodedFormEntity(postParams, "UTF-8"));
      } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      }

    // Set up the response handler
    ResponseHandler<String> handler = new ResponseHandler<String>() {

      @Override
      public String handleResponse(final HttpResponse response)
          throws ClientProtocolException, IOException {

        int status = response.getStatusLine().getStatusCode();

        logger.info("Status: " + status);
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
      }
    };
    String responseBody = null;
    try {
      responseBody = client.execute(httpPost, handler);
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return responseBody;
  }

  public String executeGet(String URLAddress,
      Map<String, String> headerParams) throws MalformedURLException {

    HttpClient client = HttpClientBuilder.create().build();
    HttpGet httpGet = new HttpGet(URLAddress);

    if (headerParams != null) {
      for (String header : headerParams.keySet()) {
        httpGet.addHeader(header, headerParams.get(header));
      }
    }

    // Set up the response handler
    ResponseHandler<String> handler = new ResponseHandler<String>() {

      @Override
      public String handleResponse(final HttpResponse response)
          throws ClientProtocolException, IOException {

        int status = response.getStatusLine().getStatusCode();

        logger.info("Status: " + status);
        HttpEntity entity = response.getEntity();
        return entity != null ? EntityUtils.toString(entity) : null;
      }
    };
    String responseBody = null;
    try {
      responseBody = client.execute(httpGet, handler);
    } catch (ClientProtocolException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return responseBody;
  }

  public String executeSSLPost(String URLAddress,
      Map<String, String> headerParams,
      List<NameValuePair> postParams) throws MalformedURLException,
      IOException, NoSuchAlgorithmException, KeyManagementException,
      KeyStoreException {

    HttpClientBuilder builder = HttpClientBuilder.create();

    SSLContext sslContext = new SSLContextBuilder()
        .loadTrustMaterial(null, new TrustStrategy() {
          public boolean isTrusted(X509Certificate[] arg0,
              String arg1) throws CertificateException {
            return true;
          }
        }).build();

    @SuppressWarnings("deprecation")
    HostnameVerifier hostnameVerifier = 
				SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

    SSLConnectionSocketFactory sslSocketFactory = 
      new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
      .<ConnectionSocketFactory> create()
      .register("http",
          PlainConnectionSocketFactory.getSocketFactory())
      .register("https", sslSocketFactory).build();

    PoolingHttpClientConnectionManager connectionMgr = 
			new PoolingHttpClientConnectionManager(socketFactoryRegistry);
    builder.setConnectionManager(connectionMgr);

    builder.setSslcontext(sslContext);

    HttpClient client = builder.build();
    HttpPost httpPost = new HttpPost(URLAddress);

    if (headerParams != null) {
      for (String header : headerParams.keySet()) {
        httpPost.addHeader(header, headerParams.get(header));
      }
    }

    // Set UTF-8 character encoding to ensure proper 
    // encoding structure in your posts
    if (postParams != null)
      httpPost
          .setEntity(new UrlEncodedFormEntity(postParams, "UTF-8"));

    // Set up the response handler
    ResponseHandler<String> handler = new ResponseHandler<String>() {

      @Override
      public String handleResponse(final HttpResponse response)
          throws ClientProtocolException, IOException {

        int status = response.getStatusLine().getStatusCode();

        logger.info("Status: " + status);
        if (status >= 200 && status < 300) {
          HttpEntity entity = response.getEntity();
          return entity != null ? EntityUtils.toString(entity) : null;
        } else {
          throw new ClientProtocolException(
              "Unexpected response status: " + status);
        }
      }
    };
    String responseBody = client.execute(httpPost, handler);
    return responseBody;
  }

  public String executeSSLGet(String URLAddress,
      Map<String, String> headerParams) throws MalformedURLException,
      IOException, KeyManagementException, NoSuchAlgorithmException,
      KeyStoreException {
    HttpClient client = HttpClients.createDefault();
    HttpGet httpget = new HttpGet(URLAddress);

    if (headerParams != null) {
      for (String header : headerParams.keySet()) {
        httpget.addHeader(header, headerParams.get(header));
      }
    }

    logger.info("Executing request " + httpget.getRequestLine());

    // Set up the response handler
    ResponseHandler<String> handler = new ResponseHandler<String>() {

      @Override
      public String handleResponse(final HttpResponse response)
          throws ClientProtocolException, IOException {

        int status = response.getStatusLine().getStatusCode();

        logger.info("Status: " + status);
        if (status >= 200 && status < 300) {
          HttpEntity entity = response.getEntity();
          return entity != null ? EntityUtils.toString(entity) : null;
        } else {
          throw new ClientProtocolException(
              "Unexpected response status: " + status);
        }
      }
    };
    String responseBody = client.execute(httpget, handler);
    return responseBody;
  }

  public String executeSSLGetAllTrusting(String URLAddress)
      throws MalformedURLException, IOException,
      KeyManagementException, NoSuchAlgorithmException,
      KeyStoreException {
    TrustManager[] allTrustingCerts = new TrustManager[] {
        new X509TrustManager() {
          @Override
          public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            logger.info("Inside TrustManager getAcceptedIssuers...");
            return null;
          }

          @Override
          public void checkClientTrusted(X509Certificate[] certs,
              String authType) throws CertificateException {
            logger.info("Inside TrustManager checkClientTrusted...");
          }

          @Override
          public void checkServerTrusted(X509Certificate[] certs,
              String authType) {
            logger.info("Inside TrustManager checkServerTrusted...");
            logger.info("certs......: " + certs);
            logger.info("authType...: " + authType);
          }
        } };

    SSLContextBuilder sslBuilder = new SSLContextBuilder();
    sslBuilder.loadTrustMaterial(null, new TrustStrategy() {
      public boolean isTrusted(X509Certificate[] chain,
          String authType) throws CertificateException {
        return true;
      }
    });

    @SuppressWarnings("deprecation")
    HostnameVerifier hostnameVerifier = 
			SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
    SSLConnectionSocketFactory sslSocketFactory = 
			new SSLConnectionSocketFactory(sslBuilder.build(), hostnameVerifier);
    CloseableHttpClient client = HttpClients.custom()
        .setSSLSocketFactory(sslSocketFactory).build();
    HttpGet httpget = new HttpGet(URLAddress);

    logger.info("Executing request " + httpget.getRequestLine());

    // Set up the response handler
    ResponseHandler<String> handler = new ResponseHandler<String>() {
      @Override
      public String handleResponse(final HttpResponse response)
          throws ClientProtocolException, IOException {

        int status = response.getStatusLine().getStatusCode();

        logger.info("Status: " + status);
        if (status >= 200 && status < 300) {
          HttpEntity entity = response.getEntity();
          return entity != null ? EntityUtils.toString(entity) : null;
        } else {
          throw new ClientProtocolException(
              "Unexpected response status: " + status);
        }
      }
    };
    String responseBody = client.execute(httpget, handler);
    return responseBody;
  }
}

Testing out using ApacheHttpClientTest

package com.avaldes.test;

import java.io.IOException;
import java.net.MalformedURLException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import com.avaldes.util.ApacheConnection;

public class ApacheHttpClientTest {
	public static void main(String[] args)
			throws MalformedURLException {

		CommandLineParser parser = new DefaultParser();
		Option help = new Option("help", "print this message");

		Options options = new Options();
		options.addOption(help);
		try {
			CommandLine cmd = parser.parse(options, args);

			if (cmd.hasOption("help")) {
				System.out.println("This help message...");
			}

		} catch (ParseException e) {
			System.err
					.println("Unable to parse command-line options -- Reason: "
							+ e.getMessage());
		}

		ApacheConnection apacheConnection = new ApacheConnection();

		// Test HTTP GET method
		Map<String, String> headers = new HashMap<String, String>();
		headers.put("header1", "headerValue1");
		headers.put("header2", "headerValue2");
		String response = apacheConnection
				.executeGet("http://httpbin.org/get", headers);
		System.out.println(response);

		// Test HTTP POST method
		List<NameValuePair> postParams = new ArrayList<NameValuePair>();
		postParams.add(new BasicNameValuePair("param1", "paramValue1"));
		postParams.add(new BasicNameValuePair("param2", "paramValue2"));
		postParams.add(new BasicNameValuePair("param3", "paramValue3"));
		response = apacheConnection.executePost("http://httpbin.org/post",
				null, postParams);
		System.out.println(response);

		// Test HTTPS GET method
		try {
			response = apacheConnection
					.executeSSLGet("https://httpbin.org/get", null);
		} catch (KeyManagementException | NoSuchAlgorithmException
				| KeyStoreException | IOException e) {
			e.printStackTrace();
		}
		System.out.println(response);

		// Test HTTPS POST method
		postParams = new ArrayList<NameValuePair>();
		postParams.add(new BasicNameValuePair("param1", "paramValue1"));
		postParams.add(new BasicNameValuePair("param2", "paramValue2"));
		postParams.add(new BasicNameValuePair("param3", "paramValue3"));
		try {
			response = apacheConnection.executeSSLPost(
					"https://httpbin.org/post", null, postParams);
		} catch (KeyManagementException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println(response);

	}
}

Output from executeGet

INFO : com.avaldes.util.ApacheConnection - Status: 200
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip,deflate", 
    "Header1": "headerValue1", 
    "Header2": "headerValue2", 
    "Host": "httpbin.org", 
    "User-Agent": "Apache-HttpClient/4.5 (Java/1.7.0_79)"
  }, 
  "url": "http://httpbin.org/get"
}

Output from executePost

INFO : com.avaldes.util.ApacheConnection - Status: 200
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Accept-Encoding": "gzip,deflate", 
    "Content-Length": "0", 
    "Host": "httpbin.org", 
    "User-Agent": "Apache-HttpClient/4.5 (Java/1.7.0_79)"
  }, 
  "json": null, 
  "url": "http://httpbin.org/post"
}

Output from executeSSLGet

INFO : com.avaldes.util.ApacheConnection - 
		Executing request GET https://httpbin.org/get HTTP/1.1
INFO : com.avaldes.util.ApacheConnection - Status: 200
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "gzip,deflate", 
    "Host": "httpbin.org", 
    "User-Agent": "Apache-HttpClient/4.5 (Java/1.7.0_79)"
  }, 
  "url": "https://httpbin.org/get"
}

Output from executeSSLPost

INFO : com.avaldes.util.ApacheConnection - Status: 200
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "param1": "paramValue1",
    "param2": "paramValue2",
    "param3": "paramValue3"
  }, 
  "headers": {
    "Accept-Encoding": "gzip,deflate", 
    "Content-Length": "56", 
    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", 
    "Host": "httpbin.org", 
    "User-Agent": "Apache-HttpClient/4.5 (Java/1.7.0_79)"
  }, 
  "json": null, 
  "url": "https://httpbin.org/post"
}

Download the Complete Source Code

That’s It!

I hope you enjoyed this tutorial. It was certainly a lot of fun putting it together and testing it out. Please continue to share the love and like us so that we can continue bringing you quality tutorials. Happy Coding!!!

apacheHttpClient

Related JAX-RS Tutorial Posts

  • RESTful Web Services with AngularJS, Bootstrap and Java using JAX-RS and Jersey
    In this tutorial we will develop a full blown CRUD application using JAX-RS API and Jersey to implement RESTful web services. JAX-RS stands for Java API for RESTful Web Services and by using this powerful API developers can easily build REST services. Jersey RESTful Web Services is an open source framework for developing RESTful Web Services in Java that provides support for JAX-RS APIs.
  • JAX-RS Security using JSON Web Encryption(JWE) with AngularJS, Bootstrap, Grid-UI and MongoDB Example
    In this tutorial we will discuss how to use AngularJS, Bootstrap and Grid-UI to connect to secure JAX-RS RESTful web services using JWE/JWT/JWS for Authentication and Authorization. In our example implementation, we will be using Symmetric Encryption where the receiver and sender share a common key.
  • JAX-RS Security using JSON Web Encryption (JWE) with JWS/JWT for Authentication and Authorization
    In this tutorial we will discuss how to secure JAX-RS RESTful web services using JSON Web Encryption(JWE), JSON Web Key (JWK), JSON Web Signature(JWS), and JSON Web Tokens(JWT) for Authentication and Authorization. JSON Web Encryption (JWE) encrypted content using Javascript Object Notation (JSON) based structures.
  • JAX-RS Security using JSON Web Tokens (JWT) for Authentication and Authorization
    In this tutorial we will discuss how to secure JAX-RS RESTful web services using JSON Web Tokens Authentication and Authorization. This form of security is used for authenticating a client using a signed token which can be verified by application servers. This token-based form of security is a ideal candidate for Cross-domain (CORS) access and when server-side scalability is a prime motivation factor.
  • JAX-RS Security using API-KEY for Authorization
    In this tutorial we will discuss how to secure JAX-RS RESTful web services using API-KEY or Service Key for Authorization. This form of security is used to ensure that certain RESTful endpoints are protected against unauthorized use.
  • JAX-RS Security using Digest Authentication and Authorization
    In this JAX-RS Digest Authentication and Authorization tutorial we will discuss how to set up digest security for our RESTful web service. This form of access authentication is slightly more complex than the previously discussed JAX-RS Basic Authentication Tutorial.
  • JAX-RS Security using Basic Authentication and Authorization
    In this JAX-RS basic authentication and authorization tutorial we will discuss how to set up security for our RESTful web service. We will need to ensure that some of the URIs are protected and only clients that have been authenticated and authorized are able to gain access and make use of them.
  • Upload and Download Multiple Binary Files using MongoDB
    In this tutorial we are going to develop multiple file upload and file download capability using RESTful web service using JAX-RS and Jersey storing the contents of files into MongoDB Database using a powerful feature in MongoDB for managing large files called GridFS.
  • Inserting and Retrieving Binary Data with MongoDB using JAX-RS RESTful Web Service
    In this tutorial we are going to develop file upload and file download capability using RESTful web service using JAX-RS and Jersey storing the contents of files into MongoDB Database using a powerful feature in MongoDB for managing large files called GridFS. The bulk of the framework for this tutorial came from my previous tutorial so you find many similarities between the two posts.
  • Inserting and Retrieving Binary Data with SQL Server Database using JAX-RS RESTful Web Service
    In this tutorial we are going to develop file upload and file download capability using RESTful web service using JAX-RS and Jersey storing the contents of the file into SQL Server Database using BLOB. Our example will be able to store PDF files, Excel files, Word Document files, Powerpoint files, Image files, or any other type of file available us provided we have ample amount of storage space.
  • File Download Example Using RESTful Web Service with JAX-RS and Jersey
    In this example we are going to develop file download capability using RESTful web service using JAX-RS and Jersey. As you will see, downloading a File using Jersey is very easy as it uses the HTTP GET for the file operations. In our web service, we will be allowing you to download the file via two mechanisms. You will be able to download by HTTP query parameters via @QueryParam and also by using the path parameters via @PathParam.
  • JAX-RS Restful Web Services with JNDI Datasource for MySQL in Tomcat
    In this tutorial we will discuss how to set up JAX-RS RESTful web services and configure a JNDI Datasource with Connection Pooling in Tomcat and connect to MYSQL Database. JNDI (Java Naming and Directory Interface) provides and interface to multiple naming and directory services.
  • File Upload Example Using RESTful Web Service with JAX-RS and Jersey
    In this example we are going to develop file upload capability using RESTful web service using JAX-RS and Jersey. As you will see, uploading a File using Jersey is pretty straight forward as it uses HTTP POST with the encoding type of multipart/form-data for the file operations.
  • RESTful Web Services @FormParam Example using JAX-RS and Jersey
    In this example we are going to develop a simple RESTful web service using JAX-RS and Jersey to extract form parameters submitted by a form using @FormParam annotation.
  • RESTful Web Services @MatrixParam Example using JAX-RS and Jersey
    In this example we are going to develop a simple RESTful web service using JAX-RS and Jersey to extract matrix parameters from the request URL using the @MatrixParam annotations.
  • RESTful Web Services @QueryParam Example using JAX-RS and Jersey
    In this example we are going to develop a simple RESTful web service using JAX-RS and Jersey to extract query parameters from the request URL using the @QueryParam annotation.
  • RESTful Web Services @PathParam Example using JAX-RS and Jersey
    In this example we are going to develop a simple RESTful web service using JAX-RS and Jersey to extract path parameters from the request URL using the @PathParam annotation.

Please Share Us on Social Media

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *