Http Util Class Make HttpURLConnection And OkHttp Reusable

This example shows you how to encapsulate HttpURLConnection and OkHttp in an HTTP util class that can make HTTP requests through HttpURLConnection or OkHttp reusable.

1. Encapsulate HttpURLConnection Or OkHttp Diagram.

  1. Because HTTP request is a frequently used function, so we had better encapsulate it in a util class.
  2. Also because HTTP request is a synchronous process, it may take a long time to block the main thread.
  3. So we had better encapsulate HTTP request action in a child thread. In the child thread’s run method, we do the HTTP request logic.
  4. This will lead to an issue that is when the thread start, the main thread continues to run to the exit.
  5. But the HTTP process in the child thread does not complete, so the main thread can not get HTTP response data.
  6. To resolve this issue, we create a callback object that is used when the HTTP request process is complete in the child thread.
  7. When the request succeeds, it will invoke the callback object’s onSuccess method, when the request fails, it will call the callback object’s onFailure method.
  8. This way, we can transfer HTTP request/response data out to the main thread through the callback object when the child thread is complete.
  9. But please remember, because the callback object runs in the child thread, so we have to use a message handler in the main activity to update UI controls.

2. HTTP Util Class Example.

If you can not watch the above video, you can see it on the youtube URL https://youtu.be/8_O6RARpqg8

  1. Click the first button will get the HTTP response header and body string from www.bing.com.
  2. Click the second button will get and display header and body data from www.baidu.com.

2.1 HTTP Util Class File Structure.

  1. This example contains the below 3 core java files.
    D:\WORK\DEV2QA.COM-EXAMPLE-CODE\ANDROIDEXAMPLEPROJECT\EXAMPLE\APP\SRC\MAIN\JAVA\COM\DEV2QA\EXAMPLE\NETWORK\UTIL
        HttpCallback.java
        HttpTool.java
        HttpToolActivity.java

2.2 HTTP Util Class.

  1. This is the HTTP util class java file. It contains two methods, one encapsulates HttpURLConnection the other encapsulates OkHttp.
  2. HttpTool.java
    package com.dev2qa.example.network.util;
    
    import android.webkit.URLUtil;
    
    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.FormBody;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    
    
    public class HttpTool {
    
        public static final String HTTP_REQUEST_METHOD_GET = "GET";
    
        public static final String HTTP_REQUEST_METHOD_POST = "POST";
    
        private static final int CONNECTION_TIME_OUT = 10000;
    
        private static final int READ_TIME_OUT = 10000;
    
        /*This method will send HTTP requests using HttpURLConnection.
          Because the process will be executed in a child thread that can avoid main thread block.
          So this method needs a httpCallback input parameter that will process the request result asynchronously.
    
          String urlString: The HTTP target URL.
          String method: GET or POST.
          Map<String, String> postParamsMap: If the request method is post, then this is the post parameters map.
          HttpCallback httpCallback: This is the object which will process the request result when the HTTP request is complete in the child thread.
          */
        public static void sendHttpRequestUseHttpURLConnection(final String urlString, final String method, final Map<String, String> postParamsMap, final HttpCallback httpCallback)
        {
            // Create a thread object.
            Thread workerThread = new Thread()
            {
                @Override
                public void run() {
                    // Declare HttpURLConnection object.
                    HttpURLConnection httpURLConnection = null;
                    try
                    {
                        // Check whether the url address string is valid or not.
                        if(!URLUtil.isHttpsUrl(urlString) && !URLUtil.isHttpUrl(urlString))
                        {
                            Exception ex = new Exception(urlString + " is not a valid http or https url. The url must start with http or https.");
                            throw ex;
                        }else {
                            // Create URL object.
                            URL url = new URL(urlString);
    
                            // Open URLConnection.
                            URLConnection urlConnection = url.openConnection();
    
                            // Cast to HttpURLConnection.
                            httpURLConnection = (HttpURLConnection)urlConnection;
    
                            // Set request method.
                            httpURLConnection.setRequestMethod(method);
    
                            // Set connection timeout value.
                            httpURLConnection.setConnectTimeout(CONNECTION_TIME_OUT);
    
                            // Set read timeout value.
                            httpURLConnection.setReadTimeout(READ_TIME_OUT);
    
                            // If http post request.
                            if(HTTP_REQUEST_METHOD_POST.equals(method))
                            {
                                // Write output stream.
                                httpURLConnection.setDoOutput(true);
    
                                // Get post parameters key value pair from postParamsMap.
                                StringBuffer postParamsBuf = new StringBuffer();
                                if( postParamsMap != null )
                                {
                                    // Loop the key and value in map object.
                                    Set<String> keySet = postParamsMap.keySet();
                                    Iterator<String> it = keySet.iterator();
                                    while(it.hasNext())
                                    {
                                        String key = it.next();
                                        String value = postParamsMap.get(key);
    
                                        // Append url key value pair.
                                        postParamsBuf.append(key);
                                        postParamsBuf.append("=");
                                        postParamsBuf.append(value);
                                        postParamsBuf.append("&");
                                    }
                                }
    
                                // Read input stream.
                                httpURLConnection.setDoInput(true);
    
                                // Get output stream from http url connection to post data to server.
                                OutputStream outputStream = httpURLConnection.getOutputStream();
                                // Create output stream writer.
                                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
                                // Create buffered writer to make write more efficiency.
                                BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
                                // Write post params to server.
                                bufferedWriter.write(postParamsBuf.toString());
    
                                // Do not forget flush and close output stream at end.
                                bufferedWriter.flush();
                                outputStreamWriter.flush();
                                outputStream.flush();
    
                                bufferedWriter.close();
                                outputStreamWriter.close();
                                outputStream.close();
                            }
    
                            // Get header fields map.
                            Map<String, List<String>> headerFieldsMap = httpURLConnection.getHeaderFields();
    
                            // Get input stream.
                            InputStream inputStream = httpURLConnection.getInputStream();
    
                            // Create input stream reader.
                            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
    
                            // Create buffered input stream reader.
                            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
    
                            StringBuffer respBuffer = new StringBuffer();
    
                            // Read line of response string.
                            String lineData = bufferedReader.readLine();
    
                            while(lineData != null)
                            {
                                // Append the line string if is not null.
                                respBuffer.append(lineData);
                                lineData = bufferedReader.readLine();
                            }
    
                            bufferedReader.close();
                            inputStreamReader.close();
                            inputStream.close();
    
    
                            if(httpCallback != null)
                            {
                                // Call custom callback object's onSuccess method with the response string.
                                httpCallback.onSuccess(respBuffer.toString(), headerFieldsMap);
                            }
                        }
                    }catch(Exception ex)
                    {
                        // If error occurred, call custom callback object's onFailure method with exception object.
                        httpCallback.onFailure(ex);
                    }finally
                    {
                        if( httpURLConnection != null )
                        {
                            // Disconnect http url connection.
                            httpURLConnection.disconnect();
                            httpURLConnection = null;
                        }
                    }
                }
            };
    
            // Start the child thread.
            workerThread.start();
        }
    
    
        /*This method will send HTTP requests using HttpURLConnection.
         Because the process will be executed in a child thread that can avoid main thread block.
         So this method needs a httpCallback input parameter that will process the request result asynchronously.
    
         String urlString: The HTTP target URL.
         String method: GET or POST.
         Map<String, String> postParamsMap: If the request method is post, then this is the post parameters map.
         Callback callback: This is the okhttp Callback object which will process the request result when the HTTP request is complete in the child thread.
         */
        public static void sendHttpRequestUseOkHttp(final String urlString, final String method, final Map<String, String> postParamsMap, final Callback callback)
        {
            // Create a OkHttp client.
            OkHttpClient okHttpClient = new OkHttpClient();
    
            // Create okhttp request builder.
            Request.Builder builder = new Request.Builder();
    
            // Set url address.
            builder.url(urlString);
    
            // If http post request.
            if(HTTP_REQUEST_METHOD_POST.equals(method)) {
                // Create okhttp3 form body builder.
                FormBody.Builder formBodyBuilder = new FormBody.Builder();
    
                // Add form parameters from params map.
                if (postParamsMap != null) {
                    // Get map object key set.
                    Set<String> keySet = postParamsMap.keySet();
    
                    // Get keyset iterator.
                    Iterator<String> it = keySet.iterator();
    
                    // Iterate each key and value, add key-value pair in post form body builder.
                    while (it.hasNext()) {
                        String key = it.next();
                        String value = postParamsMap.get(key);
                        formBodyBuilder.add(key, value);
                    }
                }
    
                // Build form body.
                FormBody formBody = formBodyBuilder.build();
    
                // Add http post form body.
                builder.post(formBody);
            }
    
            // Build okhttp request.
            Request request = builder.build();
    
            // Create an okhttp Call object.
            Call call = okHttpClient.newCall(request);
    
            // Execute the http request in okhttp auto started child thread.
            call.enqueue(callback);
        }
    }

2.3 Custom Http Callback Class.

  1. OkHttp has a default callback class which is okhttp.Callback.
  2. But HttpURLConnection does not have a built-in callback class, so we have to write a custom callback class for HttpURLConnection.
  3. This class has two methods, one is invoked when the request is success the other is called when the request fails.
  4. HttpCallback.java
    package com.dev2qa.example.network.util;
    
    import android.util.Log;
    
    import java.util.List;
    import java.util.Map;
    
    
    public class HttpCallback {
    
        // Log tag string.
        private static final String TAG_HTTP_CALL_BACK = "TAG_HTTP_CALL_BACK";
    
        /* This method is invoked when HTTP request success.
        *  String respString : This is the response page text.
        *  Map<String, List<String>> headerFieldsMap : This is the response header fields map.
        * */
        public void onSuccess(String respString, Map<String, List<String>> headerFieldsMap)
        {
            Log.d(TAG_HTTP_CALL_BACK, respString);
        }
    
    
        // This method is invoked when HTTP request failed.
        public void onFailure(Exception ex)
        {
            Log.e(TAG_HTTP_CALL_BACK, ex.getMessage(), ex);
        }
    }

2.4 Main Activity Class.

  1. HttpToolActivity.java
    package com.dev2qa.example.network.util;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.support.v7.app.AppCompatActivity;
    import android.text.TextUtils;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import com.dev2qa.example.R;
    
    import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import okhttp3.Call;
    import okhttp3.Headers;
    import okhttp3.Response;
    
    public class HttpToolActivity extends AppCompatActivity {
    
        private Button sendUseHttpURLConnectionButton = null;
    
        private Button sendUseOkHttpButton = null;
    
        private TextView showResultTextView = null;
    
        private Handler showResultHandler = null;
    
        private static final int MESSAGE_SHOW_RESULT = 1;
    
        private static final String KEY_RESULT = "KEY_RESULT";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_http_tool);
    
            setTitle("dev2qa.com - Http Request Wrapper Tool Example.");
    
            // Initialize this example UI controls.
            initControls();
    
            // When click send http request use HttpURLConnection button.
            sendUseHttpURLConnectionButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    // Create a new custom HttpCallback instance.
                    HttpCallback httpCallback = new HttpCallback(){
                        @Override
                        public void onSuccess(String respString, Map<String, List<String>> headerFieldsMap) {
                            StringBuffer respBuf = new StringBuffer();
    
                            // Append response header data.
                            Set<String> keySet = headerFieldsMap.keySet();
                            Iterator<String> it = keySet.iterator();
                            while(it.hasNext())
                            {
                                String headerName = it.next();
    
                                if(headerName!=null && !TextUtils.isEmpty(headerName.trim())) {
                                    List<String> headerValueList = headerFieldsMap.get(headerName);
    
                                    respBuf.append(headerName);
                                    respBuf.append(" = ");
    
                                    if(headerValueList != null)
                                    {
                                        for(String headerValue : headerValueList)
                                        {
                                            respBuf.append(headerValue);
                                            respBuf.append(" , ");
                                        }
                                    }
    
                                    respBuf.append(" \r\n\r\n ");
                                }
                            }
    
                            // Append response body string.
                            respBuf.append(respString);
    
                            showHttpRequestResult(respBuf.toString());
                        }
    
                        @Override
                        public void onFailure(Exception ex) {
                            showHttpRequestResult("Http request error, exception class name : " + ex.getClass().getSimpleName() + " , exception message : " + ex.getMessage());
                        }
                    };
    
                    // Send http request use HttpURLConnection.
                    HttpTool.sendHttpRequestUseHttpURLConnection("http://www.bing.com", HttpTool.HTTP_REQUEST_METHOD_GET, null, httpCallback);
                }
            });
    
            // Click this button to send http request through OkHttp..
            sendUseOkHttpButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    // Create a OkHttp Callback instance.
                    okhttp3.Callback okhttpCallback = new okhttp3.Callback(){
    
                        @Override
                        public void onFailure(Call call, IOException ex) {
                            showHttpRequestResult("Http request error, exception class name : " + ex.getClass().getSimpleName() + " , exception message : " + ex.getMessage());
                        }
    
                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            StringBuffer respBuf = new StringBuffer();
    
                            // Append response header data.
                            Headers headers = response.headers();
                            Set<String> headerNames = headers.names();
                            Iterator<String> it = headerNames.iterator();
                            while(it.hasNext())
                            {
                                String headerName = it.next();
                                String headerValue = headers.get(headerName);
    
                                respBuf.append(headerName);
                                respBuf.append(" = ");
                                respBuf.append(headerValue);
                                respBuf.append("\r\n\r\n");
    
                            }
    
                            // Append response body string.
                            String respString = response.body().string();
                            respBuf.append(respString);
    
                            showHttpRequestResult(respBuf.toString());
                        }
                    };
    
                    // Send http request use OkHttp3.
                    HttpTool.sendHttpRequestUseOkHttp("http://www.baidu.com", HttpTool.HTTP_REQUEST_METHOD_GET, null, okhttpCallback);
                }
            });
    
        }
    
        private void initControls()
        {
            if(sendUseHttpURLConnectionButton == null)
            {
                sendUseHttpURLConnectionButton = (Button)findViewById(R.id.http_tool_send_use_httpurlconnection_button);
            }
    
            if(sendUseOkHttpButton == null)
            {
                sendUseOkHttpButton = (Button)findViewById(R.id.http_tool_send_use_okhttp_button);
            }
    
            if(showResultTextView == null)
            {
                showResultTextView = (TextView)findViewById(R.id.http_tool_show_page_result_view);
            }
    
            if(showResultHandler == null)
            {
                // This Handler is used to listen to child thread 'show http request result page' message..
                showResultHandler = new Handler()
                {
                    @Override
                    public void handleMessage(Message msg) {
                        // If show request result page.
                        if(msg.what == MESSAGE_SHOW_RESULT)
                        {
                            // Get result page text.
                            Bundle bundle = msg.getData();
                            String pageData = bundle.getString(KEY_RESULT);
    
                            // Show text in textview.
                            showResultTextView.setText(pageData);
                        }
                    }
                };
            }
        }
    
    
        /* Because each call back object will be executed in a child thread,
        *  so we still need to update the activity UI in main thread use Handler.*/
        private void showHttpRequestResult(String respString)
        {
            Message msg = new Message();
            msg.what = MESSAGE_SHOW_RESULT;
    
            Bundle bundle = new Bundle();
            bundle.putString(KEY_RESULT, respString);
    
            msg.setData(bundle);
    
            showResultHandler.sendMessage(msg);
        }
    
    }
    

2.5 Layout XML File.

  1. activity_http_tool.xml
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="http://www.bing.com"/>
    
        <Button
            android:id="@+id/http_tool_send_use_httpurlconnection_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Send Request With HTTPURLConnection"
            android:textAllCaps="false"/>
    
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="http://www.baidu.com"/>
    
        <Button
            android:id="@+id/http_tool_send_use_okhttp_button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Send Request With OkHttp"
            android:textAllCaps="false"/>
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <TextView
                android:id="@+id/http_tool_show_page_result_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
    
        </ScrollView>
    
    </LinearLayout>

2.6 Android Manifest Xml File.

  1. AndroidManifest.xml
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.dev2qa.example">
    
        <!-- Required permission. -->
    
        <uses-permission android:name="android.permission.INTERNET" />
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            
            <activity android:name=".network.util.HttpToolActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

Leave a Comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.