美文网首页
OkHttp封装

OkHttp封装

作者: zhi5ai | 来源:发表于2022-08-04 11:00 被阅读0次

    基于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

    相关文章

      网友评论

          本文标题:OkHttp封装

          本文链接:https://www.haomeiwen.com/subject/ynuswrtx.html