OkHttp封装

基于com.squareup.okhttp:okhttp:2.6.0

请求类型

application/x-www-form-urlencoded和application/json的那些事儿_不丸子的博客

常用HTTP请求编码格式之application/x-www-form-urlencoded、application/json_Greenhand

总结 http post请求 application/x-www-form-urlencoded body体数据获取不到(zoukankan.com)

Axios的两种请求类型的区别( application/json;charset=utf-8 、x-www-form-urlencoded)

通过@RequestBody或者@RequestParam接收传输参数
json的两种情况:传递json字符串。传递json对象
1、json对象类型:Content type:application/x-www-form-urlencoded;charset=UTF-8。

2、json为字符串类型:Content type:application/json;charset=UTF-8。

OkHttpUtils

package com.example.okhttp;

import com.android.okhttp.OkHttpClient;
import com.android.okhttp.Request;
import com.android.okhttp.RequestBody;
import com.android.okhttp.Response;
import com.android.okhttp.FormEncodingBuilder;
import com.android.okhttp.Callback;
import com.android.okhttp.Call;
import com.android.okhttp.MediaType;

import android.util.Log;
import java.io.IOException;
import com.example.okhttp.ICallBack;
import com.example.okhttp.Utils;

import java.util.HashMap;
import java.util.Map;

public class OkHttpUtils {
    private static final String TAG = "OkHttpUtils";
    public static final String secret = "^xxO.........Tn";


    private OkHttpClient okHttpClient;

    private static OkHttpUtils mInstance;
    public static OkHttpUtils getInstance(){
        if (mInstance == null) {
            synchronized (OkHttpUtils.class) {
                if (mInstance == null) {
                    mInstance = new OkHttpUtils();
                }
            }           
        }
        return mInstance;
    }

    private OkHttpUtils() {     
        this.okHttpClient = new OkHttpClient();
    }

    public <T> void post(String url, HashMap<String, Object> params, ICallBack iCallBack) {
        FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder();
        for (String key : params.keySet()) {
            formEncodingBuilder.add(key, params.get(key).toString());
        }
        
        String sign = "";
        try {
            sign = Utils.getSignature(params, secret);
        } catch (IOException e) {
            Log.d(TAG, "getSignature exception: " + e);
        }
    
        formEncodingBuilder.add("sign", sign);
        String transId = Utils.getTransactionId();

        Request request = new Request.Builder()
                .header("transactionid",transId)
                .url(url)
                .post(formEncodingBuilder.build())
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                iCallBack.onFailed(e.toString());
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if(response.isSuccessful()){
                    String body = response.body().string();
                    String result = Utils.toURLDecoder(body);
                    iCallBack.onSuccess(result);
                }
            }
        });
    }

    public <T> void post(String url, String json, ICallBack iCallBack) {
        String transId = Utils.getTransactionId();
        MediaType JSON = MediaType.parse("application/json;charset=utf-8");
        RequestBody requestBody = RequestBody.create(JSON, json);
        Request request = new Request.Builder()
                .header("transactionid",transId)
                .url(url)
                .post(requestBody)
                .build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                iCallBack.onFailed(e.toString());
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if(response.isSuccessful()){
                    String body = response.body().string();
                    String result = Utils.toURLDecoder(body);
                    iCallBack.onSuccess(result);
                }
            }
        });
    }

    public void download(final String url, final String destFileDir, final String destFileName, final OnDownloadListener listener) {
        Request request = new Request.Builder()
                .url(url)
                .build();

        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                listener.onDownloadFailed(e);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if(response.isSuccessful()){
                    InputStream is = null;
                    byte[] buf = new byte[2048];
                    int len = 0;
                    FileOutputStream fos = null;

                    //储存下载文件的目录
                    File dir = new File(destFileDir);
                    dir.delete();
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    File file = new File(dir, destFileName);
                    Log.e("----:", " " + file);
                    try {
                        is = response.body().byteStream();
                        long total = response.body().contentLength();
                        fos = new FileOutputStream(file);
                        long sum = 0;
                        int old = 0;
                        while ((len = is.read(buf)) != -1) {
                            fos.write(buf, 0, len);
                            sum += len;
                            int progress = (int) (sum * 1.0f / total * 100);
                            if (old == progress) {
                                continue;
                            }
                            old = progress;
                            //下载中更新进度条
                            listener.onDownloading(progress);
                        }
                        fos.flush();
                        //下载完成
                        listener.onDownloadSuccess(file);
                    } catch (Exception e) {
                        listener.onDownloadFailed(e);
                    } finally {
                        try {
                            if (is != null) {
                                is.close();
                            }
                            if (fos != null) {
                                fos.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }        
                    }
                }
            }
        });
    }   
}

ICallback.java

public interface ICallBack {
    void onSuccess(String result);
    void onFailed(String failed);
}

OnDownloadListener

import java.io.File;
    
public interface OnDownloadListener {
   /**
      * 下载成功之后的文件
      */
    void onDownloadSuccess(File file);
   /**
      * 下载进度
      */
    void onDownloading(int progress);

   /**
      * 下载异常信息
      */
    void onDownloadFailed(Exception e);
}   

工具类 Utils.java

签名生成算法
URL解码
序列号生成: yyyyMMddHHmmssSSS+15 位随机数
实体类转HashMap

import java.util.*;

import java.util.Map.Entry;
import java.util.HashMap;
import java.util.Map;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.GeneralSecurityException;
import java.util.Set;
import java.util.TreeMap;

import java.net.URLDecoder;
import java.io.UnsupportedEncodingException;

import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;

import java.lang.StringBuffer;
import java.util.Random;

import android.util.Log;
import java.lang.reflect.Field;
    
public class Utils {

    /**
 * 签名生成算法
 * @param HashMap<String,String> params 请求参数集,所有参数必须已转换为字符串类型
 * @param String secret 签名密钥
 * @return 签名
 * @throws IOException
 */
    public static String getSignature(HashMap<String,Object> params, String secret) throws IOException
    {
        // 先将参数以其参数名的字典序升序进行排序
        Map<String, Object> sortedParams = new TreeMap<String, Object>(params);
        Set<Entry<String, Object>> entrys = sortedParams.entrySet();
     
        // 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
        StringBuilder basestring = new StringBuilder();
        for (Entry<String, Object> param : entrys) {
            basestring.append(param.getKey()).append("=").append(param.getValue().toString()).append("|");
        }
        basestring.append(secret);
     
        // 使用MD5对待签名串求签
        byte[] bytes = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            bytes = md5.digest(basestring.toString().getBytes("UTF-8"));
        } catch (GeneralSecurityException ex) {
            throw new IOException(ex);
        }
     
        // 将MD5输出的二进制结果转换为小写的十六进制
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex);
        }
        return sign.toString();
    }   

    public static String toURLDecoder(String param) {
        if (param == null || param.equals("")) {
            return "";          
        }

        try {
            String url = new String(param.getBytes(), "UTF-8");
            url = URLDecoder.decode(url, "UTF-8");
            return url;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**

    * -获取带毫秒时间戳,格式化时间:“yyyyMMddHHmmssSSS”

    * @return

    */

    public static String getTransactionId(){
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        String temp = dtf.format(LocalDateTime.now());
        // 生成15位随机序列
        String randomSte = getRandomString(15);
        return temp + randomSte;
    }

    private static String getRandomString(int length) { // length表示生成字符串的长度
     //   String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString().toUpperCase();
    }

     //实体类转HashMap-第二种方法-建议
    public static HashMap<String,Object> transitionEntity(Object onClass){
        HashMap<String,Object> hashMap = new HashMap<String,Object>();
        Field[] fields = onClass.getClass().getDeclaredFields();
        for(Field field:fields){
            //反射时让私有变量变成可访问
            field.setAccessible(true);
            try {
                hashMap.put(field.getName(),field.get(onClass));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return hashMap;
    }
    
}

调用方式 POST

 private void postReportUpgradeResult() {
        ReportData report = createReportlists();    
        //report --> HashMap 
        HashMap<String, Object> map = Utils.transitionEntity(report);
        OkHttpUtils.getInstance().post(reportUpgradeUrl, map, new ICallBack() {
            @Override
            public void onFailed(String e) {
                Log.d(TAG, "onFailed: " + e);
            }

            @Override
            public void onSuccess(String response) {
                Log.d(TAG, "onSuccess-->: " + response); 
                Gson gson = new Gson();
                ReportBean reportBean = gson.fromJson(response, ReportBean.class);
                int result = reportBean .getResult;
                ...
            }
        });
   }

   private void postJsonReportUpgradeResult() {
        ReportData report = createReportlists();
       //report --> json
        Gson gson = new Gson();
        String postJson = gson.toJson(report);
        OkHttpUtils.getInstance().post(reportUpgradeUrl, postJson, new ICallBack() {
            @Override
            public void onFailed(String e) {
                Log.d(TAG, "onFailed: " + e);
            }

            @Override
            public void onSuccess(String response) {
                Log.d(TAG, "onSuccess json-->: " + response);                        
            }
        });
   }

  private void downloadFile(String url, String filepath, String filename) {
        OkHttpUtils.getInstance().download(url, filepath, filename, new OnDownloadListener(){
            @Override
            public void onDownloadSuccess(File file) {
                Log.d(TAG, "download success ");                                     
            }

            @Override
            public void onDownloading(int progress) {
                Log.d(TAG, "downloading --->: " + progress);
            }

            @Override
            public void onDownloadFailed(Exception e) {
                Log.d(TAG, "download exception: " + e);
            }
        });
   }

HTTPS


        this.okHttpClient = new OkHttpClient(); 
        okHttpClient.setSslSocketFactory(SSLSocketClient.getSSLSocketFactory());
import javax.net.ssl.*;
import java.security.cert.X509Certificate;
import java.security.SecureRandom;


public class SSLSocketClient {
    public static SSLSocketFactory getSSLSocketFactory() {
        try {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, getTrustManager(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);

        }
    }

    private static TrustManager[] getTrustManager(){
        TrustManager[] trustAllCerts = new TrustManager[]{
            new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType){
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType){
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[]{};
                }
            }
        };
        return trustAllCerts;
    }
}

OKHttp实现Https请求_jianning-wu的博客-CSDN博客_okhttp 请求https
OkHttp配置HTTPS访问+服务器部署
OKHTTP里HTTPS的使用
android https okhttp实现https请求 - it610.com
Android实现https双向认证/单向认证 okhttp+Retrofit+https) (freesion.com)
Android-OKhttp解决https安全链接请求问题 (freesion.com)
Android HTTPS 自制证书实现双向认证(OkHttp + Retrofit + Rxjava)) (freesion.com)
okhttp访问https的问题 - 简书 (jianshu.com)
OkHttp配置HTTPS访问+服务器部署okhttpclient 访问https
Java调用Http/Https接口(8,end)--OkHttp调用Http/Https接口 (cnblogs.com)
OkHttp的Https认证问题 - 简书 (jianshu.com)
OkHttp中https的使用 - 简书 (jianshu.com)

拦截器

okhttp之OkHttpClient - it610.com

断电续传

...
(待完成)

OkHttp认识与使用 - 简书 (jianshu.com)
OkHttp原理解析 - 简书 (jianshu.com)
OkHttp3学习(一):基本使用 - SegmentFault 思否
OkHttp3学习(二):发送一个请求 - SegmentFault 思否
OkHttp3学习(三):execute和Interceptor - SegmentFault 思否

OKHttp使用简介_chenzujie的博客-CSDN博客
OKHttp源码解析(一)_chenzujie的博客-CSDN博客
OKHttp源码解析(二)_chenzujie的博客-CSDN博客
OKHttp源码解析(三)_chenzujie的博客-CSDN博客

OkHttp单例模式,GET请求和POST请求(全家桶)okhttp 单例
OKHttp的介绍和基本用法_小飞侠-2的博客-CSDN博客

okhttp各种请求报文你真的懂吗?_HXL~的博客
HTTP请求详解含POST,GET实例_phineasGuo的博客
OkHttp3封装网络请求框架_如风少年的博客
Android开发神器:OkHttp框架源码解析 - 简书 (jianshu.com)

android OKHTTP文件下载工具类_lizhong的技术博客_51CTO博客

使用OKHttp3实现下载(断点续传、显示进度) - it610.com
android 利用okhttp实现apk下载,带进度_Dr_abandon新秀_android okhttp下载
使用okhttp下载文件 、传统方式下载文件,简介okhttp使用(Java)_suqinyi的博客
okhttp下载文件,下载apk - 简书 (jianshu.com)
Android OkHttp + Retrofit 下载文件与进度监听_9433135的技术博客_51CTO博客
OkHttp断点续传及文件下载思路_WayneSun729的博客-okhttp 断点下载

(写的都非常好的文档!!)

工具

在线JSON字符串转Java实体类(JavaBean、Entity)-BeJSON.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容