package com.arialyy.frame.http; import android.content.Context; import android.os.Handler; import android.os.Looper; import android.support.annotation.NonNull; import android.text.TextUtils; import com.arialyy.frame.cache.CacheUtil; import com.arialyy.frame.http.inf.IResponse; import com.arialyy.frame.util.show.L; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; import okhttp3.Call; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.Headers; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; /** * Created by lyy on 2015/11/5. * 网络连接工具 */ public class HttpUtil { private static final String TAG = "HttpUtil"; private Context mContext = null; private static volatile HttpUtil mUtil = null; private static final Object LOCK = new Object(); private CacheUtil mCacheUtil; private Handler mHandler; private static final int TIME_OUT = 5000; public static final String CONTENT_TYPE_IMG = "image/*"; public static final String CONTENT_TYPE_TEXT = "text/*"; public static final String CONTENT_TYPE_FILE = "application/octet-stream"; private HttpUtil() { } private HttpUtil(Context context) { mContext = context; mCacheUtil = new CacheUtil(mContext, false); mHandler = new Handler(Looper.getMainLooper()); } public static HttpUtil getInstance(Context context) { if (mUtil == null) { synchronized (LOCK) { if (mUtil == null) { mUtil = new HttpUtil(context); } } } return mUtil; } public void get(final @NonNull String url, @NonNull final IResponse absResponse) { get(url, null, absResponse, false); } public void get(final @NonNull String url, @NonNull final IResponse absResponse, boolean useCache) { get(url, null, absResponse, useCache); } public void get(final @NonNull String url, final Map<String, String> params, @NonNull final IResponse absResponse) { get(url, params, absResponse, false); } public void post(final @NonNull String url, @NonNull final IResponse absResponse) { post(url, null, null, absResponse, false); } public void post(final @NonNull String url, final Map<String, String> params, @NonNull final IResponse absResponse) { post(url, params, null, absResponse, false); } public void post(final @NonNull String url, final Map<String, String> params, @NonNull final IResponse absResponse, final boolean useCache) { post(url, params, null, absResponse, useCache); } public void post(final @NonNull String url, final Map<String, String> params, final Map<String, String> header, @NonNull final IResponse absResponse) { post(url, params, header, absResponse, false); } /** * 上传文件 * * @param key 上传文件键值 */ public void uploadFile(@NonNull final String url, @NonNull final String filePath, @NonNull final String key, final String contentType, final Map<String, String> header, @NonNull final IResponse absResponse) { new Thread(new Runnable() { @Override public void run() { File file = new File(filePath); String BOUNDARY = UUID.randomUUID().toString(); // 边界标识 随机生成 String PREFIX = "--", LINE_END = "\r\n"; String CONTENT_TYPE = "multipart/form-data"; // 内容类型 try { HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setReadTimeout(5000); conn.setConnectTimeout(5000); conn.setDoInput(true); conn.setDoOutput(true); conn.setUseCaches(false); conn.setRequestMethod("POST"); conn.setRequestProperty("Charset", "utf-8"); // 设置编码 conn.setRequestProperty("connection", "keep-alive"); conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary=" + BOUNDARY); if (header != null && header.size() > 0) { Set set = header.entrySet(); for (Object aSet : set) { Map.Entry entry = (Map.Entry) aSet; conn.setRequestProperty(entry.getKey() + "", entry.getValue() + ""); } } OutputStream outputSteam = conn.getOutputStream(); DataOutputStream dos = new DataOutputStream(outputSteam); StringBuilder sb = new StringBuilder(); sb.append(PREFIX); sb.append(BOUNDARY); sb.append(LINE_END); sb.append("Content-Disposition: form-data; name=\"").append(key).append("\"; filename=\"").append(file.getName()).append("\"").append(LINE_END); sb.append("Content-Type:").append(contentType).append("; charset=utf-8").append(LINE_END); sb.append(LINE_END); dos.write(sb.toString().getBytes()); InputStream is = new FileInputStream(file); byte[] bytes = new byte[1024]; int len = 0; while ((len = is.read(bytes)) != -1) { dos.write(bytes, 0, len); } is.close(); dos.write(LINE_END.getBytes()); byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes(); dos.write(end_data); dos.flush(); int res = conn.getResponseCode(); if (res == 200) { BufferedInputStream inputStream = new BufferedInputStream(conn.getInputStream()); byte[] buf = new byte[1024]; StringBuilder stringBuilder = new StringBuilder(); while (inputStream.read(buf) > 0) { stringBuilder.append(new String(buf, 0, buf.length)); } String data = stringBuilder.toString(); L.j(data); absResponse.onResponse(data); } else { absResponse.onError("error"); } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } /** * 基本get方法 */ public void get(final @NonNull String url, final Map<String, String> params, @NonNull final IResponse absResponse, final boolean useCache) { L.v(TAG, "请求链接 >>>> " + url); String requestUrl = url; if (params != null && params.size() > 0) { Set set = params.entrySet(); int i = 0; requestUrl += "?"; for (Object aSet : set) { i++; Map.Entry entry = (Map.Entry) aSet; requestUrl += entry.getKey() + "=" + entry.getValue() + (i < params.size() ? "&" : ""); } L.v(TAG, "请求参数为 >>>> "); L.m(params); } OkHttpClient client = new OkHttpClient.Builder().connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS) .writeTimeout(TIME_OUT, TimeUnit.MILLISECONDS).readTimeout(300000, TimeUnit.MILLISECONDS).build(); final Request request = new Request.Builder().url(requestUrl).build(); Call call = client.newCall(request); //请求加入调度 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { L.e(TAG, "请求链接【" + url + "】失败"); String data = null; if (useCache) { data = mCacheUtil.getStringCache(url + L.m2s(params)); L.d(TAG, "数据获取成功,获取到的数据为 >>>> "); L.j(data); } if (TextUtils.isEmpty(data)) { setOnError(request, absResponse); } else { setOnResponse(data, absResponse); } } @Override public void onResponse(Call call, Response response) throws IOException { String data = response.body().string(); L.d(TAG, "数据获取成功,获取到的数据为 >>>> "); L.j(data); if (useCache) { L.v(TAG, "缓存链接【" + url + "】的数据"); mCacheUtil.putStringCache(url + L.m2s(params), data); } setOnResponse(data, absResponse); } }); } /** * 基本的Post方法 */ public void post(final @NonNull String url, final Map<String, String> params, final Map<String, String> header, @NonNull final IResponse absResponse, final boolean useCache) { L.v(TAG, "请求链接 >>>> " + url); OkHttpClient client = new OkHttpClient.Builder().connectTimeout(TIME_OUT, TimeUnit.MILLISECONDS) .writeTimeout(TIME_OUT, TimeUnit.MILLISECONDS).readTimeout(300000, TimeUnit.MILLISECONDS).build(); FormBody.Builder formB = new FormBody.Builder(); //头数据 Headers.Builder hb = new Headers.Builder(); if (header != null && header.size() > 0) { Set set = header.entrySet(); for (Object aSet : set) { Map.Entry entry = (Map.Entry) aSet; hb.add(entry.getKey() + "", entry.getValue() + ""); } L.v(TAG, "请求的头数据为 >>>> "); L.m(header); } //请求参数 if (params != null && params.size() > 0) { Set set = params.entrySet(); for (Object aSet : set) { Map.Entry entry = (Map.Entry) aSet; formB.add(entry.getKey() + "", entry.getValue() + ""); } L.v(TAG, "请求参数为 >>>> "); L.m(params); } else { formB.add("null", "null"); } Request request = new Request.Builder().url(url).post(formB.build()).headers(hb.build()).build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { L.e(TAG, "请求链接【" + url + "】失败"); String data = null; if (useCache) { data = mCacheUtil.getStringCache(url + L.m2s(params)); L.d(TAG, "从缓存读取的数据为 >>>> "); L.j(data); } if (TextUtils.isEmpty(data)) { setOnError(call, absResponse); } else { setOnResponse(data, absResponse); } } @Override public void onResponse(Call call, Response response) throws IOException { String data = response.body().string(); L.d(TAG, "数据获取成功,获取到的数据为 >>>>"); L.j(data); if (useCache) { L.v(TAG, "缓存链接【" + url + "】的数据"); mCacheUtil.putStringCache(url + L.m2s(params), data); } setOnResponse(data, absResponse); } }); } private void setOnError(final Object error, final IResponse response) { mHandler.post(new Runnable() { @Override public void run() { response.onError(error); } }); } private void setOnResponse(final String data, final IResponse response) { mHandler.post(new Runnable() { @Override public void run() { response.onResponse(data); } }); } /** * 返回String类型的响应 */ public static class AbsResponse implements IResponse { @Override public void onResponse(String data) { } @Override public void onError(Object error) { } } }