com.hellofyc.base.net.http.HttpUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.hellofyc.base.net.http.HttpUtils.java

Source

/*
 *  Copyright (C) 2012-2015 Jason Fang ( ifangyucun@gmail.com )
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.hellofyc.base.net.http;

import android.graphics.Bitmap;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.v4.util.ArrayMap;
import android.text.TextUtils;

import com.hellofyc.base.utils.EncodeUtils;
import com.hellofyc.base.utils.FLog;
import com.hellofyc.base.utils.IoUtils;

import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.UUID;

public class HttpUtils {

    private static final int TYPE_TEXT = 1;
    private static final int TYPE_BITMAP = 2;
    private static final int TYPE_FILE = 3;

    private static final String BOUNDARY = UUID.randomUUID().toString();

    private static final String CONTENT_TYPE_TEXT = "application/x-www-form-urlencoded";
    private static final String CONTENT_TYPE_FILE = "multipart/form-data; boundary=" + BOUNDARY;
    private static final String PREFIX = "--";

    private static final String LINE_END = "\r\n";

    private boolean mDebug = false;
    private boolean mStackTrace = false;
    private HttpRequest mRequestParams = new HttpRequest();
    private Method mMethod = Method.POST;
    private String mUrlString;
    private int mConnectTimeout = 30 * 1000;
    private int mReadTimeout = 30 * 1000;
    private Bitmap mBitmap;
    private ArrayMap<String, File> mFileMap;
    private int mType = TYPE_TEXT;
    private String mUserAgent = "Android";

    protected HttpUtils() {
    }

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

    public HttpUtils setReqeustParams(@NonNull HttpRequest requestParams) {
        mRequestParams = requestParams;
        return this;
    }

    public HttpUtils setMethod(@NonNull Method method) {
        mMethod = method;
        return this;
    }

    public HttpUtils setUrl(@NonNull String urlString) {
        mUrlString = urlString;
        return this;
    }

    public HttpUtils setReadTimeout(@IntRange(from = 1) int readTimeoutInMillis) {
        mReadTimeout = readTimeoutInMillis;
        return this;
    }

    public HttpUtils setConnectTimeout(@IntRange(from = 1) int connectTimeoutInMills) {
        mConnectTimeout = connectTimeoutInMills;
        return this;
    }

    public HttpUtils setDebugEnable() {
        mDebug = true;
        return this;
    }

    public HttpUtils setStackTraceEnable() {
        mStackTrace = true;
        return this;
    }

    public HttpUtils setBitmap(@NonNull Bitmap bitmap) {
        mType = TYPE_BITMAP;
        mBitmap = bitmap;
        return this;
    }

    public HttpUtils setFiles(@NonNull Map<String, File> fileMap) {
        mType = TYPE_FILE;
        if (mFileMap == null) {
            mFileMap = new ArrayMap<>();
        }
        mFileMap.putAll(fileMap);
        return this;
    }

    public HttpUtils setUserAgent(@NonNull String userAgent) {
        mUserAgent = userAgent;
        return this;
    }

    public HttpResponse request() {
        if (mDebug) {
            FLog.i("REQUEST URL:" + mUrlString);
            FLog.i("REQUEST PARAMS:" + mRequestParams.getArrayMap().toString());
            FLog.i("REQUEST STRING:" + mRequestParams.getString());
        }

        if (mStackTrace) {
            getInvokeStackTraceElement();
        }

        HttpResponse response = new HttpResponse();
        HttpURLConnection connection = null;
        try {
            connection = (HttpURLConnection) new URL(mUrlString).openConnection();
            configConnection(connection);
            response.code = connection.getResponseCode();
            if (mDebug)
                FLog.i("===responseCode:" + response.code);
            if (response.code == HttpURLConnection.HTTP_OK) {
                String responseText = IoUtils.readStream(connection.getInputStream());
                String cookie = connection.getHeaderField("Set-Cookie");
                if (mDebug)
                    FLog.i("===responseText:" + responseText);
                if (mDebug)
                    FLog.i("===cookie:" + cookie);
                response.cookies = HttpCookie.parse(cookie);
                response.text = responseText;
            } else {
                response.text = connection.getResponseMessage();
            }
        } catch (UnknownHostException e) {
            if (mDebug)
                FLog.e(e);
            response.code = HttpResponse.STATUS_CODE_NET;
            response.text = "";
            return response;
        } catch (IOException e) {
            if (mDebug)
                FLog.e(e);
            response.code = HttpResponse.STATUS_CODE_UNKNOWN;
            response.text = "UNKNOWN";
            return response;
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
        return response;
    }

    private static byte[] bitmapToBytes(@NonNull Bitmap bitmap) {
        byte[] bytes = new byte[bitmap.getWidth() * bitmap.getHeight()];
        for (int i = 0; i < bitmap.getWidth(); i++) {
            for (int j = 0; j < bitmap.getHeight(); j++) {
                bytes[i + j] = (byte) (bitmap.getPixel(i, j) & 0x80 >> 7);
            }
        }
        return bytes;
    }

    protected void configConnection(HttpURLConnection connection) throws IOException {
        connection.setConnectTimeout(mConnectTimeout);
        connection.setReadTimeout(mReadTimeout);
        connection.setUseCaches(false);
        connection.setDoInput(true);
        connection.setRequestProperty("Charset", Charset.defaultCharset().name());
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("User-Agent", mUserAgent);
        connection.setInstanceFollowRedirects(false);
        connection.setRequestProperty("Cookie", CookieHelper.parse(mRequestParams.getCookies()));

        switch (mType) {
        case TYPE_TEXT: {
            connection.setRequestMethod(mMethod.name());
            if (mMethod == Method.POST) {
                connection.setDoOutput(true);
                connection.setRequestProperty("Content-Type", CONTENT_TYPE_TEXT);
                String paramsString;
                if (!TextUtils.isEmpty(mRequestParams.getString())) {
                    paramsString = mRequestParams.getString();
                } else {
                    paramsString = parseMapToUrlParamsString(mRequestParams.getArrayMap());
                }
                DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
                outputStream.write(paramsString.getBytes());
                outputStream.flush();
                outputStream.close();
            }
            break;
        }
        case TYPE_BITMAP: {
            connection.setRequestMethod(Method.POST.name());
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", CONTENT_TYPE_FILE);
            DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());

            StringBuilder builder = new StringBuilder();
            for (Map.Entry<String, Object> entry : mRequestParams.getArrayMap().entrySet()) {
                builder.append(PREFIX).append(BOUNDARY).append(LINE_END);
                builder.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append("\"")
                        .append(LINE_END);
                builder.append("Content-Type: text/plain; charset=\"utf-8\"").append(LINE_END);
                builder.append("Content-Transfer-Encoding: 8bit").append(LINE_END);
                builder.append(LINE_END);
                builder.append(entry.getValue());
                builder.append(LINE_END);
            }
            outputStream.write(builder.toString().getBytes());

            outputStream.writeBytes(PREFIX + BOUNDARY + LINE_END);
            outputStream.writeBytes("Content-Disposition: form-data; name=\"" + "bitmap" + "\";filename=\""
                    + "bitmap.jpg" + "\"" + LINE_END);
            outputStream.writeBytes(LINE_END);
            outputStream.write(bitmapToBytes(mBitmap));
            outputStream.writeBytes(LINE_END);
            outputStream.writeBytes(PREFIX + BOUNDARY + PREFIX + LINE_END);
            outputStream.flush();
            outputStream.close();
            break;
        }
        case TYPE_FILE: {
            connection.setRequestMethod(Method.POST.name());
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", CONTENT_TYPE_FILE);

            DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());

            StringBuilder builder = new StringBuilder();
            for (Map.Entry<String, Object> entry : mRequestParams.getArrayMap().entrySet()) {
                builder.append(PREFIX).append(BOUNDARY).append(LINE_END);
                builder.append("Content-Disposition: form-data; name=\"").append(entry.getKey()).append("\"")
                        .append(LINE_END);
                builder.append("Content-Type: text/plain; charset=\"utf-8\"").append(LINE_END);
                builder.append("Content-Transfer-Encoding: 8bit").append(LINE_END);
                builder.append(LINE_END);
                builder.append(entry.getValue());
                builder.append(LINE_END);
            }

            for (ArrayMap.Entry<String, File> entry : mFileMap.entrySet()) {
                String text = PREFIX + BOUNDARY + LINE_END + "Content-Disposition: form-data; name=\""
                        + entry.getKey() + "\"; filename=\"" + entry.getValue().getName() + "\"" + LINE_END
                        + "Content-Type:" + "application/octet-stream" + LINE_END
                        + "Content-Transfer-Encoding: binary" + LINE_END + LINE_END;
                outputStream.writeBytes(builder.append(text).toString());

                BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(entry.getValue()));
                int length;
                byte[] bytes = new byte[1024 * 1024];
                while ((length = inputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, length);
                }
                inputStream.close();
            }

            String endTag = LINE_END + PREFIX + BOUNDARY + PREFIX + LINE_END;
            outputStream.writeBytes(endTag);
            outputStream.flush();
            outputStream.close();
            break;
        }
        }
    }

    public String parseMapToUrlParamsString(ArrayMap<String, Object> paramsMap) {
        if (paramsMap == null || paramsMap.size() == 0)
            return "";

        StringBuilder sb = new StringBuilder();
        int size = paramsMap.size();
        for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
            size--;
            if (TextUtils.isEmpty(entry.getKey()))
                continue;
            sb.append(entry.getKey());
            sb.append("=");
            sb.append(entry.getValue() == null ? "" : EncodeUtils.encode(String.valueOf(entry.getValue())));
            sb.append(size == 0 ? "" : "&");
        }
        return sb.toString();
    }

    private static void getInvokeStackTraceElement() {
        FLog.i("Thread ID: " + Thread.currentThread().getId() + " getInvokeStackTraceElement");
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        for (StackTraceElement element : stackTraceElements) {
            FLog.i("(" + element.getLineNumber() + ") " + "class name:" + element.getClassName() + ", method name:"
                    + element.getMethodName());
        }
    }
}