OkHttp封装

2022-08-04  本文已影响0人  zhi5ai

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

上一篇 下一篇

猜你喜欢

热点阅读