BlocNotes

Notepad of a tinker, maker, hacker or whatever you call it :)

Android - Send a HTTP(S) POST request

As a part of my ioPush Android application, I needed to send a POST request to a secure server. I found some example over the internet but nothing parametric.
Here is my code, with optional basic HTTP authentication and headers:

Packages importation

// Required for httpPost() method
import java.io.InputStream;  
import java.net.URL;  
import javax.net.ssl.HttpsURLConnection;  
import javax.net.ssl.SSLContext;  
import android.util.Base64;  
import java.io.BufferedReader;  
import java.io.InputStreamReader;  
import java.io.BufferedWriter;  
import java.io.OutputStreamWriter;  
import java.io.OutputStream;  
import java.net.HttpURLConnection;  
// Required for JSON handling
import org.json.JSONException;  
import org.json.JSONObject;  

POST request

private HttpResultHelper httpPost(String urlStr, String user, String password, String data, ArrayList<String[]> headers, int timeOut) throws IOException  
    {
        // Set url
        URL url = new URL(urlStr);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();

        // If secure connection
        if (urlStr.startsWith("https")) {
            try {
                SSLContext sc;
                sc = SSLContext.getInstance("TLS");
                sc.init(null, null, new java.security.SecureRandom());
                ((HttpsURLConnection)conn).setSSLSocketFactory(sc.getSocketFactory());
            } catch (Exception e) {
                Log.d(TAG, "Failed to construct SSL object", e);
            }
        }


        // Use this if you need basic authentication
        if ((user != null) && (password != null)) {
            String userPass = user + ":" + password;
            String basicAuth = "Basic " + Base64.encodeToString(userPass.getBytes(), Base64.DEFAULT);
            conn.setRequestProperty("Authorization", basicAuth);
        }

        // Set Timeout and method
        conn.setReadTimeout(timeOut);
        conn.setConnectTimeout(timeOut);
        conn.setRequestMethod("POST");
        conn.setDoOutput(true);

        if (headers != null) {
            for (int i = 0; i < headers.size(); i++) {
                conn.setRequestProperty(headers.get(i)[0], headers.get(i)[1]);
            }
        }

        if (data != null) {
            conn.setFixedLengthStreamingMode(data.getBytes().length);
            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(data);
            writer.flush();
            writer.close();
            os.close();
        }

        InputStream inputStream = null;
        try
        {
            inputStream = conn.getInputStream();
        }
        catch(IOException exception)
        {
            inputStream = conn.getErrorStream();
        }

        HttpResultHelper result = new HttpResultHelper();
        result.setStatusCode(conn.getResponseCode());
        result.setResponse(inputStream);

        return result;
    }

How to call it
URL encoded with basic authentication

HttpResultHelper httpResult = httpPost("https://ioPush.net/app/api/getAuthToken", "**@ioPush.net", "**", null, null, 7000);  
  BufferedReader in = new BufferedReader(new InputStreamReader(httpResult.getResponse()));
  String result = "";
  String inputLine;
  while ((inputLine = in.readLine()) != null) {
    result += inputLine;
  }

How to call it
JSON data with custom headers

  String result = "";
  String inputLine;
  // JSON data
  JSONObject data = new JSONObject();
  try {
    data.put("key1", "param1");
    data.put("key2", param2);
    data.put("key3", "param3");
  } catch (JSONException e) {
    e.printStackTrace();
  }
  // Headers
  ArrayList<String[]> headers = new ArrayList<>();
  headers.add(new String[]{"custom-header", "custom value"});
  headers.add(new String[]{"Content-Type", "application/json"});
  httpResult = httpPost("https://url.ext/page", null, null, data.toString(), headers, 7000);
  BufferedReader in = new BufferedReader(new InputStreamReader(httpResult.getResponse()));
  while ((inputLine = in.readLine()) != null) {
    result += inputLine;
  }

HttpResultHelpers
Mandatory class to return status code and response.

import java.io.InputStream;

public class HttpResultHelper {  
    private int statusCode;
    private InputStream response;

    public HttpResultHelper() {
    }

    public int getStatusCode() {
        return statusCode;
    }

    public void setStatusCode(int statusCode) {
        this.statusCode = statusCode;
    }

    public InputStream getResponse() {
        return response;
    }

    public void setResponse(InputStream response) {
        this.response = response;
    }
}