123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701 |
- package com.edufound.android.xyyf.util;
- import android.os.Handler;
- import android.os.Looper;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.FileNameMap;
- import java.net.URLConnection;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import okhttp3.Call;
- import okhttp3.Callback;
- import okhttp3.Cookie;
- import okhttp3.CookieJar;
- import okhttp3.FormBody;
- import okhttp3.Headers;
- import okhttp3.HttpUrl;
- import okhttp3.Interceptor;
- import okhttp3.MediaType;
- import okhttp3.MultipartBody;
- import okhttp3.OkHttpClient;
- import okhttp3.Request;
- import okhttp3.RequestBody;
- import okhttp3.Response;
- import okhttp3.ResponseBody;
- import okio.Buffer;
- import okio.BufferedSource;
- import okio.ForwardingSource;
- import okio.Okio;
- public class OKHttpUtil {
- private OkHttpClient okHttpClient;
- private Handler handler;
- private static OKHttpUtil mInstance;
- private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
- private OKHttpUtil() {
- //添加cookie
- okHttpClient = new OkHttpClient.Builder().cookieJar(new CookieJar() {
- @Override
- public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
- cookieStore.put(url.host(), cookies);
- }
- @Override
- public List<Cookie> loadForRequest(HttpUrl url) {
- List<Cookie> cookies = cookieStore.get(url.host());
- return cookies != null ? cookies : new ArrayList<Cookie>();
- }
- }).build();
- handler = new Handler(Looper.getMainLooper());
- }
- /**
- * 单例模式创建OkHttpUtil
- *
- * @return mInstance
- */
- public static OKHttpUtil getInstance() {
- if (mInstance == null) {
- synchronized (OKHttpUtil.class) {
- mInstance = new OKHttpUtil();
- }
- }
- return mInstance;
- }
- /**
- * get 同步请求
- *
- * @return response
- */
- private Response _getDataSync(String url) {
- Request request = new Request.Builder()
- .get()//默认get,可省略
- .url(url)
- .build();
- Response response = null;
- try {
- response = okHttpClient.newCall(request).execute();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return response;
- }
- /**
- * get 同步请求
- *
- * @return 字符串
- */
- private String _getDataString(String url) throws IOException {
- Response response = _getDataSync(url);
- if (response.body() != null) {
- return response.body().string();
- }
- return null;
- }
- /**
- * get 异步请求
- */
- private void _getDataAsync(String url, final ResultCallback callback) {
- final Request request = new Request.Builder()
- .url(url)
- .build();
- deliveryResult(callback, request);
- }
- /**
- * post 同步请求
- *
- * @return response
- */
- private Response _postDataSync(String url, Param... params) throws IOException {
- Request request = buildPostRequest(url, params);
- return okHttpClient.newCall(request).execute();
- }
- /**
- * post 同步请求
- *
- * @return 字符串
- */
- private String _postDataString(String url, Param... params) throws IOException {
- Response response = _postDataSync(url, params);
- return response.body().string();
- }
- /**
- * post 异步请求
- */
- private void _postDataAsync(String url, final ResultCallback callback, Param... params) {
- Request request = buildPostRequest(url, params);
- deliveryResult(callback, request);
- }
- /**
- * post 异步请求
- */
- private void _postDataAsync(String url, final ResultCallback callback, Map<String, String> params) {
- Param[] paramsArr = map2Params(params);
- Request request = buildPostRequest(url, paramsArr);
- deliveryResult(callback, request);
- }
- /**
- * post 同步文件上传
- */
- private Response _postDataFileSync(String url, File[] files, String[] fileKeys, Param... params) throws IOException {
- Request request = buildMultipartFormRequest(url, files, fileKeys, params);
- return okHttpClient.newCall(request).execute();
- }
- private Response _postDataFileSync(String url, File file, String fileKey) throws IOException {
- Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, null);
- return okHttpClient.newCall(request).execute();
- }
- private Response _postDataFileSync(String url, File file, String fileKey, Param... params) throws IOException {
- Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, params);
- return okHttpClient.newCall(request).execute();
- }
- /**
- * 异步基于post的多文件上传
- */
- private void _postDataFileAsync(String url, final ResultCallback callback, File[] files, String[] fileKeys, Param... params) {
- Request request = buildMultipartFormRequest(url, files, fileKeys, params);
- deliveryResult(callback, request);
- }
- /**
- * 异步基于post的文件上传,单文件不带参数上传
- *
- * @param url
- * @param callback
- * @param file
- * @param fileKey
- */
- private void _postDataFileAsync(String url, ResultCallback callback, File file, String fileKey) {
- Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, null);
- deliveryResult(callback, request);
- }
- /**
- * 异步基于post的文件上传,单文件且携带其他form参数上传
- *
- * @param url 接口地址
- * @param callback callback
- * @param file file
- * @param fileKey fileKey
- * @param params params
- */
- private void _postDataFileAsync(String url, ResultCallback callback, File file, String fileKey, Param... params) {
- Request request = buildMultipartFormRequest(url, new File[]{file}, new String[]{fileKey}, params);
- deliveryResult(callback, request);
- }
- /**
- * 同步 post上传json对象
- *
- * @param url url;
- * @param jsonStr json 字符串
- * @return 字符串
- * @throws IOException
- */
- private String _postJsonDataSync(String url, String jsonStr) throws IOException {
- String result = null;
- MediaType JSON = MediaType.parse("text/html;charset=utf-8");
- RequestBody requestBody = RequestBody.create(JSON, jsonStr);
- Request request = new Request.Builder().url(url).post(requestBody).build();
- Response response = okHttpClient.newCall(request).execute();
- result = response.body().string();
- return result;
- }
- /**
- * 异步 post上传json对象
- *
- * @param url url
- * @param jsonStr json数据字符串
- * @param callback callback
- */
- private void _postJsonDataAsync(String url, String jsonStr, final ResultCallback callback) {
- MediaType JSON = MediaType.parse("text/html;charset=utf-8");
- RequestBody requestBody = RequestBody.create(JSON, jsonStr);
- Request request = new Request.Builder().url(url).post(requestBody).build();
- deliveryResult(callback, request);
- }
- /**
- * post 异步上传图片
- *
- * @param url url
- * @param callback callback
- * @param file file
- * @param fileKey fileKey
- * @param map map
- */
- private void _upLoadImg(String url, final ResultCallback callback, File file, String fileKey, Map<String, String> map) {
- Param[] params = map2Params(map);
- getInstance()._postDataFileAsync(url, callback, file, fileKey, params);
- }
- /**
- * 创建 MultipartFormRequest
- *
- * @param url 接口地址
- * @param files files
- * @param fileKeys file keys
- * @param params params
- * @return MultipartFormRequest
- */
- private Request buildMultipartFormRequest(String url, File[] files,
- String[] fileKeys, Param[] params) {
- params = validateParam(params);
- MultipartBody.Builder builder = new MultipartBody.Builder();
- for (Param param : params) {
- builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + param.key + "\""),
- RequestBody.create(null, param.value));
- }
- if (files != null) {
- RequestBody fileBody;
- for (int i = 0; i < files.length; i++) {
- File file = files[i];
- String fileName = file.getName();
- fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)), file);
- //TODO 根据文件名设置contentType
- builder.addPart(Headers.of("Content-Disposition",
- "form-data; name=\"" + fileKeys[i] + "\"; filename=\"" + fileName + "\""),
- fileBody);
- }
- }
- RequestBody requestBody = builder.build();
- return new Request.Builder()
- .url(url)
- .post(requestBody)
- .build();
- }
- private Param[] validateParam(Param[] params) {
- if (params == null)
- return new Param[0];
- else
- return params;
- }
- private String guessMimeType(String path) {
- FileNameMap fileNameMap = URLConnection.getFileNameMap();
- String contentTypeFor = fileNameMap.getContentTypeFor(path);
- if (contentTypeFor == null) {
- contentTypeFor = "application/octet-stream";
- }
- return contentTypeFor;
- }
- /**
- * 异步下载文件
- */
- private void _downloadFileAsync(final String url, final String destFileDir,
- final DownloadListener downloadListener) {
- final Request request = new Request.Builder().url(url).build();
- // 重写ResponseBody监听请求
- Interceptor interceptor = new Interceptor() {
- @Override
- public Response intercept(Chain chain) throws IOException {
- Response originalResponse = chain.proceed(chain.request());
- return originalResponse.newBuilder()
- .body(new DownloadResponseBody(originalResponse, 0, downloadListener))
- .build();
- }
- };
- OkHttpClient.Builder dlOkhttp = new OkHttpClient.Builder()
- .addNetworkInterceptor(interceptor);
- final Call call = dlOkhttp.build().newCall(request);
- call.enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- downloadListener.fail(e.getMessage());
- }
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- long length = response.body().contentLength();
- downloadListener.start(length);
- InputStream is = null;
- byte[] b = new byte[2048];
- int len;
- FileOutputStream fos = null;
- try {
- is = response.body().byteStream();
- File file = new File(destFileDir, getFileName(url));
- fos = new FileOutputStream(file);
- while ((len = is.read(b)) != -1) {
- fos.write(b, 0, len);
- }
- fos.flush();
- // 如果下载文件成功,第一个参数为文件的绝对路径
- downloadListener.complete(file.getAbsolutePath());
- } catch (Exception e) {
- downloadListener.loadfail(e.getMessage());
- } finally {
- if (is != null) {
- is.close();
- }
- if (fos != null) {
- fos.close();
- }
- }
- }
- });
- }
- private String getFileName(String path) {
- int separatorIndex = path.lastIndexOf("/");
- return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1,
- path.length());
- }
- /***************************************************************** 公共方法***************************************************/
- /**
- * get 同步请求
- *
- * @param url 接口地址
- * @return response
- */
- public static Response getDataSync(String url) {
- return getInstance()._getDataSync(url);
- }
- /**
- * get 同步请求
- *
- * @param url 接口地址
- * @return 字符串
- * @throws IOException
- */
- public static String getDataString(String url) throws IOException {
- return getInstance()._getDataString(url);
- }
- /**
- * get 异步请求
- *
- * @param url 接口地址
- */
- public static void getDataAsync(String url, final ResultCallback callback) {
- getInstance()._getDataAsync(url, callback);
- }
- /**
- * post 同步请求
- *
- * @param url url
- * @param param param
- * @return response
- * @throws IOException
- */
- public static Response postDataSync(String url, Param... param) throws IOException {
- return getInstance()._postDataSync(url, param);
- }
- /**
- * post 同步请求
- *
- * @param url url
- * @param params param
- * @return 字符串
- * @throws IOException
- */
- public static String postDataString(String url, Param... params) throws IOException {
- return getInstance()._postDataString(url, params);
- }
- /**
- * post 异步请求
- *
- * @param url url
- * @param callback 异步回调
- * @param params params
- */
- public static void postDataAsync(String url, final ResultCallback callback, Param... params) {
- getInstance()._postDataAsync(url, callback, params);
- }
- /**
- * post map集合 异步请求
- *
- * @param url url
- * @param callback callback
- * @param params params
- */
- public static void postDataAsync(String url, final ResultCallback callback, Map<String, String> params) {
- getInstance()._postDataAsync(url, callback, params);
- }
- /**
- * post 异步上传图片
- *
- * @param url url
- * @param callback callback
- * @param file file
- * @param fileKey fileKey
- * @param map map
- */
- public static void upLoadImg(String url, final ResultCallback callback, File file, String fileKey, Map<String, String> map) {
- getInstance()._upLoadImg(url, callback, file, fileKey, map);
- }
- /**
- * @param url 下载地址
- * @param destFileDir 保存地址
- * @param downloadListener downloadListener
- */
- public static void downloadFileAsync(String url, String destFileDir, DownloadListener downloadListener) {
- getInstance()._downloadFileAsync(url, destFileDir, downloadListener);
- }
- public void doGetSync(String url, Callback callback) throws IOException {
- // 创建一个Request
- Request request = new Request.Builder()
- .url(url)
- .build();
- doAsync(request, callback);
- }
- /**
- * 异步请求
- */
- public void doAsync(Request request, Callback callback) throws IOException {
- //创建请求会话
- Call call = okHttpClient.newCall(request);
- //同步执行会话请求
- call.enqueue(callback);
- }
- /**
- * map 转换为 Param
- *
- * @param params map
- * @return params
- */
- private Param[] map2Params(Map<String, String> params) {
- if (params == null) {
- return new Param[0];
- }
- int size = params.size();
- Param[] res = new Param[size];
- Set<Map.Entry<String, String>> entries = params.entrySet();
- int i = 0;
- for (Map.Entry<String, String> entry : entries) {
- res[i++] = new Param(entry.getKey(), entry.getValue());
- }
- return res;
- }
- /**
- * 创建 PostRequest
- *
- * @param url url
- * @param params params
- * @return request
- */
- private Request buildPostRequest(String url, Param[] params) {
- if (params == null) {
- params = new Param[0];
- }
- FormBody.Builder builder = new FormBody.Builder();
- for (Param param : params) {
- builder.add(param.key, param.value);
- }
- RequestBody requestBody = builder.build();
- return new Request.Builder()
- .url(url)
- .post(requestBody)
- .build();
- }
- /**
- * 抽象类,用于请求成功后的回调
- *
- * @param <T>
- */
- public static abstract class ResultCallback<T> {
- //这是请求数据的返回类型,包含常见的(Bean,List等)
- //失败回调
- public abstract void onError(Request request, Exception e);
- //成功的回调
- public abstract void onResponse(T response);
- }
- private Map<String, String> mSessions = new HashMap<>();
- /**
- * 请求回调处理方法并传递返回值
- *
- * @param callback Map类型请求参数
- * @param request Request请求
- */
- private void deliveryResult(final ResultCallback callback, final Request request) {
- okHttpClient.newCall(request).enqueue(new Callback() {
- @Override
- public void onFailure(Call call, IOException e) {
- sendFailedStringCallback(request, e, callback);
- }
- @Override
- public void onResponse(Call call, Response response) throws IOException {
- try {
- final String string = response.body().string();
- sendSuccessResultCallback(string, callback);
- } catch (IOException e) {
- sendFailedStringCallback(response.request(), e, callback);
- }
- }
- });
- }
- /**
- * 处理请求失败的回调信息方法
- *
- * @param e 错误信息
- * @param callback 回调类
- */
- private void sendFailedStringCallback(final Request request, final Exception e, final ResultCallback callback) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (callback != null)
- callback.onError(request, e);
- }
- });
- }
- /**
- * 处理请求成功的回调信息方法
- *
- * @param object 服务器响应信息
- * @param callback 回调类
- */
- private void sendSuccessResultCallback(final Object object, final ResultCallback callback) {
- handler.post(new Runnable() {
- @Override
- public void run() {
- if (callback != null) {
- callback.onResponse(object);
- }
- }
- });
- }
- public static class Param {
- public Param() {
- }
- public Param(String key, String value) {
- this.key = key;
- this.value = value;
- }
- String key;
- String value;
- }
- public class DownloadResponseBody extends ResponseBody {
- private Response originalResponse;
- private DownloadListener downloadListener;
- private long oldPoint = 0;
- public DownloadResponseBody(Response originalResponse, long startsPoint, DownloadListener downloadListener) {
- this.originalResponse = originalResponse;
- this.downloadListener = downloadListener;
- this.oldPoint = startsPoint;
- Logger.e("DownloadResponseBody");
- }
- @Override
- public MediaType contentType() {
- return originalResponse.body().contentType();
- }
- @Override
- public long contentLength() {
- return originalResponse.body().contentLength();
- }
- @Override
- public BufferedSource source() {
- return Okio.buffer(new ForwardingSource(originalResponse.body().source()) {
- private long bytesReaded = 0;
- @Override
- public long read(Buffer sink, long byteCount) throws IOException {
- long bytesRead = super.read(sink, byteCount);
- bytesReaded += bytesRead == -1 ? 0 : bytesRead;
- if (downloadListener != null) {
- downloadListener.loading((int) ((bytesReaded + oldPoint)));
- }
- return bytesRead;
- }
- });
- }
- }
- public interface DownloadListener {
- /**
- * 开始下载
- */
- void start(long max);
- /**
- * 正在下载
- */
- void loading(int progress);
- /**
- * 下载完成
- */
- void complete(String path);
- /**
- * 请求失败
- */
- void fail(String message);
- /**
- * 下载过程中失败
- */
- void loadfail(String message);
- }
- }
|