LoginSignup
1
2

More than 5 years have passed since last update.

【Android】HttpClient( HttpURLConnectionのラッパー。メソッドチェーンバージョン。

Last updated at Posted at 2017-02-07

2017/02/08
POSTが動かなかったので修正しました

はじめに

最近Androidエンジニアしてるぼく。
アプリ作ってるとHTTPリクエストしたくなるよね。
GETとかPOSTとかPUTとかDELETEとか。
基礎は「HttpURLConnection Android」でググってもらって。

HttpURLConnection使いにくいやんなー
ずっと自作のラッパー使ってたんやけどなー
使い古しすぎ&他クラスとの結合度高すぎやなー
なので、いい加減作り直した。
*残念ながらmultipart/form-dataのPOST未対応。そのうちやる。
*残念ながら動作確認はしていません。

・変更点
最近メソッドチェーンがマイブームやねんってことでメソッドチェーンに
マルチスレッド処理をAsyncTask→Thred+Runnableに
コールバックをinterfaceに
パラメータとかを自作のParamクラスで受け取ってたのやめ
レスポンスの加工までHttpClientでやってたのやめた
IxJava導入した
IOUtils発見した

下準備

【Java】HTTPステータスコード列挙型 Powered by Wikipediaを実装

・以下、追記

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

実装

Githubに上げるのとかなんかナウくて嫌いなのでここで。

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:クッキーとかセッションとか。schooのソースにあるな。

/**
 * HTTPクライアント
 */
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);
    }
}

使い方

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));
            }
        });
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2