[Android] HttpClient (wrapper of HttpURLConnection. Method chain version.

2017/02/08 POST didn't work so I fixed it

Introduction

I'm an Android engineer recently. When you're making an app, you'll want to make an HTTP request. GET, POST, PUT, DELETE, etc. The basics are "HttpURLConnection Android".

HttpURLConnection It's hard to use I've been using my own rapper for a long time It's too worn out & it's too connected with other classes. So I remade it.

·change point Recently, the method chain has become my boom and it has become a method chain. Multithreaded processing changed from AsyncTask to Thred + Runnable Callback to interface I stopped receiving parameters in my own Param class I stopped using HttpClient to process the response Introduced IxJava I found IOUtils

Preparation

-Implemented [Java] HTTP status code enumeration Powered by Wikipedia

・ Additional notes below

build.gradle


dependencies {
    compile 'com.github.akarnokd:ixjava:0.90.0'
    compile 'org.apache.directory.studio:org.apache.commons.io:2.4'
}

AndroidManifest.xml


<uses-permission android:name="android.permission.INTERNET" />

Implementation

I hate uploading it to Github because it's now, so here.

HttpClient


package com.akippa.akippacore.http;

import android.net.Uri;
import android.text.TextUtils;

import org.apache.commons.io.IOUtils;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import ix.Ix;
import rx.functions.Action1;
import rx.functions.Func1;

// TODO:Cookies and sessions. It's in the schoo source.

/**
 *HTTP client
 */
public final class HttpClient {

    public enum HttpMethod {
        GET("GET"),
        POST("POST"),
        DELETE("DELETE"),
        PUT("PUT");

        private final String mValue;

        HttpMethod(String value) {
            mValue = value;
        }

        @Override
        public String toString() {
            return mValue;
        }
    }

    private final Uri.Builder mBuilder;
    private Map<String, String> mRequestParameter = new HashMap<>();
    private String mEncode = "UTF-8";
    private HttpMethod mMethod = HttpMethod.GET;
    private int mConnectTimeout = 5000;
    private int mReadTimeout = 5000;
    private Map<String, String> mRequestProperty = new HashMap<>();
    private Proxy.Type mProxyType;
    private String mProxyServerAddress;
    private int mProxyServerPort;

    private HttpClient() {
        super();
        mBuilder = new Uri.Builder();
    }

    public static HttpClient create() {
        return new HttpClient();
    }

    public HttpClient setScheme(String scheme) {
        mBuilder.scheme(scheme);
        return this;
    }

    public HttpClient setEncodedAuthority(String authority) {
        mBuilder.encodedAuthority(authority);
        return this;
    }

    public HttpClient setPath(String path) {
        mBuilder.path(path);
        return this;
    }

    public HttpClient appendRequestParameter(String key, String value) {
        mRequestParameter.put(key, value);
        return this;
    }

    public HttpClient appendRequestParamter(final Map<String, String> param) {
        Ix.from(param.keySet()).forEach(new Action1<String>() {
            @Override
            public void call(String s) {
                mRequestParameter.put(s, param.get(s));
            }
        });
        return this;
    }

    public HttpClient setEncode(String encode) {
        mEncode = encode;
        return this;
    }

    public HttpClient setMethod(HttpMethod method) {
        mMethod = method;
        return this;
    }

    public HttpClient setConnectTimeout(int connectTimeout) {
        mConnectTimeout = connectTimeout;
        return this;
    }

    public HttpClient setReadTimeout(int readTimeout) {
        mReadTimeout = readTimeout;
        return this;
    }

    public HttpClient setRequestProperty(String key, String value) {
        mRequestProperty.put(key, value);
        return this;
    }

    public HttpClient setRequestProperty(Map<String, String> requestProperty) {
        mRequestProperty = requestProperty;
        return this;
    }

    public HttpClient setProxy(Proxy.Type proxyType, String serverAddress, int serverPort) {
        mProxyType = proxyType;
        mProxyServerAddress = serverAddress;
        mProxyServerPort = serverPort;
        return this;
    }

    private HttpURLConnection createConnection() throws IOException {
        switch (mMethod) {
            case GET:
            case DELETE:
                Ix.from(mRequestParameter.keySet()).forEach(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        mBuilder.appendQueryParameter(s, mRequestParameter.get(s));
                    }
                });
                break;
        }

        final HttpURLConnection httpURLConnection = mProxyServerAddress == null
                ? (HttpURLConnection) new URL(URLDecoder.decode(mBuilder.build().toString(), mEncode)).openConnection()
                : (HttpURLConnection) new URL(URLDecoder.decode(mBuilder.build().toString(), mEncode)).openConnection(new Proxy(mProxyType, new InetSocketAddress(mProxyServerAddress, mProxyServerPort)));
        httpURLConnection.setRequestMethod(mMethod.toString());
        httpURLConnection.setConnectTimeout(mConnectTimeout);
        httpURLConnection.setReadTimeout(mReadTimeout);
        Ix.from(mRequestProperty.keySet()).forEach(new Action1<String>() {
            @Override
            public void call(String s) {
                httpURLConnection.setRequestProperty(s, mRequestProperty.get(s));
            }
        });
        switch (mMethod) {
            case POST:
            case PUT:
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setDoInput(true);
                httpURLConnection.setUseCaches(false);
                final String requestBody = TextUtils.join("&",
                        Ix.from(mRequestParameter.keySet()).map(new Func1<String, String>() {
                            @Override
                            public String call(String s) {
                                try {
                                    return String.format("%s=%s",
                                            URLEncoder.encode(s, "UTF-8"),
                                            URLEncoder.encode(mRequestParameter.get(s), "UTF-8"));
                                } catch (UnsupportedEncodingException e) {
                                    e.printStackTrace();
                                }
                                return "";
                            }
                        }).toArray(new String[]{}));
                if (requestBody.length() > 0) {
                    final OutputStream outputStream = httpURLConnection.getOutputStream();
                    final BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, mEncode));
                    bufferedWriter.write(requestBody);
                    bufferedWriter.flush();
                    bufferedWriter.close();
                    outputStream.flush();
                    outputStream.close();
                }
                break;
        }
        return httpURLConnection;
    }

    public void sendRequest(final SendRequestCallBack callBack) {
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        final HttpURLConnection httpURLConnection;
                        try {
                            httpURLConnection = createConnection();
                        } catch (IOException e) {
                            e.printStackTrace();
                            return;
                        }

                        HttpStatusCode httpStatusCode;
                        try {
                            httpURLConnection.connect();
                            httpStatusCode = HttpStatusCode.getByStatusCode(httpURLConnection.getResponseCode());
                        } catch (IOException e) {
                            e.printStackTrace();
                            callBack.onFailure(HttpStatusCode.DEFAULT);
                            return;
                        }

                        try {
                            callBack.onSuccess(httpStatusCode, IOUtils.toString(httpURLConnection.getInputStream()));
                        } catch (IOException e) {
                            e.printStackTrace();
                            callBack.onFailure(httpStatusCode);
                        }
                    }
                }
        ).start();
    }

    public interface SendRequestCallBack {

        void onFailure(HttpStatusCode code);

        void onSuccess(HttpStatusCode code, String responseText);
    }
}

How to use

sample


HttpClient.create()
        .setScheme("https")
        .setEncodedAuthority("www.google.co.jp")
        .setPath("search")
        .appendRequestParameter("q", "akippa")
        .appendRequestParameter("rct", "j")
        .setMethod(HttpClient.HttpMethod.GET)
        .sendRequest(new HttpClient.SendRequestCallBack() {
            @Override
            public void onFailure(HttpStatusCode code) {
                Log.d("log", String.format("HttpStatusCode:%s", code.toString()));
            }

            @Override
            public void onSuccess(HttpStatusCode code, String responseText) {
                Log.d("log", String.format("HttpStatusCode:%s : Response:%s", code.toString(), responseText));
            }
        });

Recommended Posts

[Android] HttpClient (wrapper of HttpURLConnection. Method chain version.
[Java] Handling of JavaBeans in the method chain
Method name of method chain in Java Builder + α
RxSwift method chain