【简单封装】OkHttp(包含cookie)

PzOkHttp类

public class PzOkHttp {
    private static final String TAG = "PzOkHttp";

    private static OkHttpClient client = null;

    private volatile static PzOkHttp http;

    private PzOkHttp() {
        if (client == null) {
            client = new OkHttpClient.Builder()
                    .connectionPool(new ConnectionPool(32, 20, TimeUnit.MILLISECONDS))
                    .protocols(Collections.singletonList(Protocol.HTTP_1_1))
                    .pingInterval(15, TimeUnit.SECONDS)
                    .retryOnConnectionFailure(false)
                    .connectTimeout(15, TimeUnit.SECONDS)//设置连接超时时间
                    .readTimeout(30, TimeUnit.SECONDS)//设置读取超时时间
                    .cookieJar(new PersistenceCookieJar())
                    .build();
        }
    }

    //双重检测锁模式 防止多线程下指令重排
    public static PzOkHttp getInstance() {
        if (http == null) {
            synchronized (PzOkHttp.class) {
                if (http == null) {
                    http = new PzOkHttp();//不是原子性操作
                }
            }
        }
        return http;
    }

    public static OkHttpClient getClient() {
        return client;
    }

    public static class PersistenceCookieJar implements CookieJar {
        List<Cookie> cache = new ArrayList<>();

        //Http请求结束,Response中有Cookie时候回调
        @Override
        public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
            //内存中缓存Cookie
            cache.addAll(cookies);
        }

        //Http发送请求前回调,Request中设置Cookie
        @Override
        public List<Cookie> loadForRequest(HttpUrl url) {
            //过期的Cookie
            List<Cookie> invalidCookies = new ArrayList<>();
            //有效的Cookie
            List<Cookie> validCookies = new ArrayList<>();
            try {
                for (Cookie cookie : cache) {
                    if (cookie.expiresAt() < System.currentTimeMillis()) {
                        //判断是否过期
                        invalidCookies.add(cookie);
                    } else if (cookie.matches(url)) {
                        //匹配Cookie对应url
                        validCookies.add(cookie);
                    }
                }
                //缓存中移除过期的Cookie
                cache.removeAll(invalidCookies);
            } catch (Exception e) {
                e.printStackTrace();
            }
            //返回List<Cookie>让Request进行设置
            return validCookies;
        }
    }

    /**
     * 异步Get
     *
     * @param url      地址
     * @param callBack 回调
     */
    public void okHttpGet(String url, final CallBackString callBack) {
        try {
            Request request = new Request.Builder().url(url).get().build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull final IOException e) {
                    callBack.onFailure(e);
                }

                @Override
                public void onResponse(@NotNull Call call, @NotNull final Response response) {
                    try {
                        if (response.code() == 200) {
                            callBack.onOkResponse(response.code(), Objects.requireNonNull(response.body()).string());
                        } else {
                            callBack.onFailure(new Exception("response.code:" + response.code()));
                        }
                    } catch (Exception e) {
                        callBack.onFailure(e);
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 异步Post
     *
     * @param url        地址
     * @param mParamsMap 需要post的数据
     * @param callBack   回调
     */
    public void okHttpPost(String url, Map<String, String> mParamsMap, final CallBackString callBack) {
        //        FormBody.Builder formBody = new FormBody.Builder(Charset.forName("GBK"));
        FormBody.Builder formBody = new FormBody.Builder();
        if (mParamsMap != null) {
            for (String key : mParamsMap.keySet()) {
                formBody.add(key, Objects.requireNonNull(mParamsMap.get(key)));
            }
        }

        final Request request = new Request.Builder().url(url).post(formBody.build()).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull final IOException e) {
                callBack.onFailure(e);
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull final Response response) {
                try {
                    if (response.code() == 200) {
                        callBack.onOkResponse(response.code(), Objects.requireNonNull(response.body()).string());
                    } else {
                        callBack.onFailure(new Exception("response.code:" + response.code()));
                    }
                } catch (Exception e) {
                    callBack.onFailure(e);
                }
            }
        });
    }

    /**
     * 异步Post
     *
     * @param url        地址
     * @param mParamsMap 需要post的数据
     * @param callBack   回调
     */
    public void postWithCode(String url, Map<String, String> mParamsMap, final CallBackString callBack) {
        //        FormBody.Builder formBody = new FormBody.Builder(Charset.forName("GBK"));
        FormBody.Builder formBody = new FormBody.Builder();
        if (mParamsMap != null) {
            for (String key : mParamsMap.keySet()) {
                formBody.add(key, Objects.requireNonNull(mParamsMap.get(key)));
            }
        }

        final Request request = new Request.Builder().url(url).post(formBody.build()).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull final IOException e) {
                callBack.onFailure(e);
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull final Response response) {
                try {
                    callBack.onOkResponse(response.code(), Objects.requireNonNull(response.body()).string());
                } catch (Exception e) {
                    callBack.onFailure(e);
                }
            }
        });
    }

    public Response okHttpPostEx(String url, Map<String, String> mParamsMap) {
        try {
            //FormBody.Builder formBody = new FormBody.Builder(Charset.forName("GBK"));
            FormBody.Builder formBody = new FormBody.Builder();
            if (mParamsMap != null) {
                for (String key : mParamsMap.keySet()) {
                    formBody.add(key, Objects.requireNonNull(mParamsMap.get(key)));
                }
            }
            final Request request = new Request.Builder().url(url).post(formBody.build()).build();
            return client.newCall(request).execute();
        } catch (Error | Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * UploadFile
     *
     * @param url       地址
     * @param file      需要上传的文件
     * @param mediaType 文件类型
     * @param formName  交付文件的表单名
     * @param callBack  回调
     */
    public void okHttpUploadFile(String url, File file, MediaType mediaType, String formName, final CallBackString callBack) {
        RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM).addPart(
                Headers.of("Content-Disposition", "form-data; name=\"" + formName + "\"; filename=\"" + file.getName() + "\""),
                RequestBody.create(mediaType, file)).build();

        Request request = new Request.Builder().url(url).post(requestBody).build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull final IOException e) {
                callBack.onFailure(e);
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull final Response response) {
                try {
                    callBack.onOkResponse(response.code(), response.body().string());
                } catch (IOException e) {
                    callBack.onFailure(e);
                }
            }
        });
    }

    /**
     * 下载文件
     *
     * @param url      文件网络路径
     * @param filePath 文件下载本地路径
     * @param fileName 文件名称(包含后缀)
     * @param callBack 回调
     */
    public void okHttpDownloadFile(String url, final String filePath, String fileName, final int maxFilesNum, final CallBackString callBack) {
        final File incompleteFile = new File(filePath, fileName + ".ysy");
        final File completeFile = new File(filePath, fileName);
        //创建下载中间文件
        if (!incompleteFile.exists()) {
            try {
                incompleteFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //发送下载请求
        client.newCall(new Request.Builder().url(url).build()).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                //请求失败,删除中间文件
                incompleteFile.delete();
                callBack.onFailure(e);
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                if (response.code() == 200) {
                    //请求成功,开始下载文件
                    Sink sink = Okio.sink(incompleteFile);
                    BufferedSink bufferedSink = Okio.buffer(sink);
                    bufferedSink.writeAll(response.body().source());
                    bufferedSink.close();
                    //下载完成,重新修改中间文件名称
                    incompleteFile.renameTo(completeFile);
                    //关闭Sink
                    if (bufferedSink != null) {
                        bufferedSink.close();
                    }
                    //控制文件数量
                    new Thread(() -> {
                        List<File> list = getFileSort(filePath);
                        while ((list.size() - maxFilesNum) > 0) {
                            list.get(0).delete();
                            list.remove(0);
                        }
                    }).start();
                    callBack.onOkResponse(response.code(), response.body().string());
                } else {
                    //网页返回不正确,比如文件不存在,删除中间文件
                    incompleteFile.delete();
                    callBack.onOkResponse(response.code(), null);
                }
            }
        });
    }

    /**
     * 获取目录下所有文件(按时间排序)
     *
     * @param path
     * @return
     */
    public static List<File> getFileSort(String path) {
        List<File> list = getFiles(path, new ArrayList<File>());
        if (list != null && list.size() > 0) {
            Collections.sort(list, new Comparator<File>() {
                public int compare(File file, File newFile) {
                    if (file.lastModified() < newFile.lastModified()) {
                        return -1;
                    } else if (file.lastModified() == newFile.lastModified()) {
                        return 0;
                    } else {
                        return 1;
                    }
                }
            });
        }
        return list;
    }

    /**
     * 获取目录下所有文件
     *
     * @param realpath
     * @param files
     * @return
     */
    public static List<File> getFiles(String realpath, List<File> files) {
        File realFile = new File(realpath);
        if (realFile.isDirectory()) {
            File[] subfiles = realFile.listFiles();
            for (File file : subfiles) {
                if (file.isDirectory()) {
                    getFiles(file.getAbsolutePath(), files);
                } else {
                    files.add(file);
                }
            }
        }
        return files;
    }

    /**
     * 接口
     */
    public interface CallBackString {

        void onFailure(Exception e);

        void onOkResponse(int code, String response);
    }
}

版权声明:本文为qq_36881363原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。