All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.lulihu.http.okhttp.HttpUtils Maven / Gradle / Ivy

package net.lulihu.http.okhttp;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.lulihu.ObjectKit.FileKit;
import net.lulihu.exception.RequestException;
import net.lulihu.http.MIME;
import okhttp3.*;
import okhttp3.Request.Builder;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 基于OKhttp3的HTTP协议请求封装
 */
@Slf4j
@Deprecated
public class HttpUtils {

    /**
     * 连接超时时间 /秒
     */
    private static final ThreadLocal CONNECT_TIMEOUT = new ThreadLocal<>();

    /**
     * 读取超时时间 /秒
     */
    private static final ThreadLocal READ_TIMEOUT = new ThreadLocal<>();

    /**
     * 请求参数
     */
    private static final ThreadLocal REQUEST_PARAM = new ThreadLocal<>();

    /**
     * 请求头部参数
     */
    private static final ThreadLocal REQUEST_HEADER_PARAM = new ThreadLocal<>();

    /**
     * 设置超时时间,注意该超时时间仅仅对下一条请求有效
     * 

* 设置新连接的默认连接超时。值0表示没有超时,否则在转换为毫秒时,值必须介于1和Integer.MAX_VALUE之间。 * 将TCP套接字连接到目标主机时应用connectTimeout。默认值为10秒。 * * @param connect 连接超时时间 * @param read 读取超时时间 */ public static void setTimeout(Integer connect, Integer read) { if (connect != null) CONNECT_TIMEOUT.set(connect); if (read != null) READ_TIMEOUT.set(read); } /** * 获取响应流 * * @param url 请求路径 */ public static BufferedSource getResponseSource(final String url) throws RequestException { Request request = new Builder().url(url).build(); try { Response response = sendRequest(request); ResponseBody body = response.body(); return body.source(); } catch (IOException e) { throw new RequestException("请求路径:" + url + "异常!:", e); } } /** * 下载小文件 * * @param url 网络路径 * @param filePath 文件保存路径 * @return 下载成功则为true 反之false */ public static boolean downloadSmallFile(final String url, final String filePath) throws RequestException { return downloadSmallFile(url, new File(filePath)); } /** * 下载小文件 * * @param url 网络路径 * @param file 文件对象 * @return 下载成功则为true 反之false */ public static boolean downloadSmallFile(final String url, final File file) throws RequestException { BufferedSink sink = null; BufferedSource source = null; try { source = getResponseSource(url); sink = Okio.buffer(Okio.sink(FileKit.createFile(file))); sink.writeAll(source); sink.flush(); } catch (IOException e) { e.printStackTrace(); return false; } finally { if (sink != null) try { sink.close(); } catch (IOException e) { e.printStackTrace(); } if (source != null) try { source.close(); } catch (IOException e) { e.printStackTrace(); } } return true; } /** * 请求日志 * * @param request 请求体 */ private static void requestLog(Request request) { if (log.isDebugEnabled()) { log.debug("请求地址:{}", request.url()); log.debug("请求类型:{}", request.method()); Object requestHeaderParam = REQUEST_HEADER_PARAM.get(); log.debug("请求头部参数:{}", requestHeaderParam == null ? "" : JSON.toJSONString(requestHeaderParam)); Object requestParam = REQUEST_PARAM.get(); if (requestParam != null) log.debug("请求主体参数:{}", requestParam instanceof String ? requestParam : JSON.toJSONString(requestParam)); } } /** * 发送http请求 */ private static Response sendRequest(Request request) throws RequestException, IOException { try { // 打印日志 requestLog(request); // 构建请求 Integer connectTimeout = CONNECT_TIMEOUT.get(); Integer readTimeout = READ_TIMEOUT.get(); OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(connectTimeout == null ? 10 : connectTimeout, TimeUnit.SECONDS) .readTimeout(readTimeout == null ? 10 : readTimeout, TimeUnit.SECONDS) .build(); // 响应 long startTime = System.nanoTime(); Response response = client.newCall(request).execute(); if (log.isDebugEnabled()) log.debug("请求耗时:" + (System.nanoTime() - startTime) / 1000 + " /μs"); // 请求成功 if (response.isSuccessful()) { return response; } throw new RequestException(response.code(), response.message(), response.body().string()); } finally { CONNECT_TIMEOUT.remove(); READ_TIMEOUT.remove(); REQUEST_PARAM.remove(); REQUEST_HEADER_PARAM.remove(); } } /** * 返回结果封装 */ private static T packagingResult(Request request, Class resultClazz) throws RequestException { try { Response response = sendRequest(request); String result = response.body().string(); if (log.isDebugEnabled()) log.debug("请求结果:\n {} ", result); return JSON.parseObject(result, resultClazz); } catch (IOException e) { throw new RequestException("发送地址为" + request.url() + "的请求错误", e); } } /** * 设置多部分post请求参数 */ private static void setPostParam(Map params, MultipartBody.Builder multipartBodyBuilder) { if (params != null && params.size() > 0) { for (String key : params.keySet()) { multipartBodyBuilder.addFormDataPart(key, params.get(key)); } } } /** * 设置POST请求表单参数 */ private static void setPostParam(Map params, FormBody.Builder builder) { if (params != null && params.size() > 0) { for (String key : params.keySet()) { builder.add(key, params.get(key)); } } } /** * 设置请求头部信息 */ private static Builder setHeadParam(Builder requestBuilder, Map headParam) { REQUEST_HEADER_PARAM.set(headParam); if (headParam != null && headParam.size() > 0) { for (String key : headParam.keySet()) { requestBuilder.addHeader(key, headParam.get(key)); } } return requestBuilder; } /** * POST请求 自定义表单方式提交 * * @param url 请求路径 * @param headParam 头部参数 * @param params 请求参数 * @param resultClazz 返回封装对象 * @return 封装结果 * @throws RequestException */ public static T sendPOSTNoEncode(String url, Map headParam, Map params, Class resultClazz) throws RequestException { REQUEST_PARAM.set(params); Request request = setHeadParam(new Builder().url(url).post(getNoEncodeFormBody(params).build()), headParam).build(); return packagingResult(request, resultClazz); } /** * 获取表单格式请求主体 */ private static NoEncodeFormBody.Builder getNoEncodeFormBody(Map params) { NoEncodeFormBody.Builder builder = new NoEncodeFormBody.Builder(); params.forEach(builder::add); return builder; } /** * 获取表单格式请求主体 */ private static FormBody.Builder getFormBody(Map params) { FormBody.Builder builder = new FormBody.Builder(); setPostParam(params, builder); return builder; } /** * POST请求 表单方式提交 * * @param url 请求路径 * @param headParam 头部参数 * @param params 请求参数 * @param resultClazz 返回封装对象 * @return 封装结果 * @throws RequestException */ public static T sendPOST(String url, Map headParam, Map params, Class resultClazz) throws RequestException { REQUEST_PARAM.set(params); FormBody body = getFormBody(params).build(); return sendPOST(url, headParam, body, resultClazz); } /** * POST请求 表单方式提交 * * @param url 请求路径 * @param headParam 头部参数 * @param body 自定义请求主体 * @param resultClazz 返回封装对象 * @return 封装结果 * @throws RequestException */ private static T sendPOST(String url, Map headParam, RequestBody body, Class resultClazz) throws RequestException { Request request = setHeadParam(new Builder().url(url).post(body), headParam).build(); return packagingResult(request, resultClazz); } /** * POST请求 Payload{Json}方式提交,适合复杂数据 * * @param url 请求路径 * @param headParam 头部参数 * @param params 请求参数 * @param resultClazz 返回封装对象 * @return 封装对象 * @throws RequestException */ public static T sendPOSTJson(String url, Map headParam, Map params, Class resultClazz) throws RequestException { REQUEST_PARAM.set(params); return sendPOSTJson(url, headParam, JSON.toJSONString(params), resultClazz); } public static T sendPOSTJson(String url, Map headParam, String params, Class resultClazz) throws RequestException { REQUEST_PARAM.set(params); // 构建请求主体参数 RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), params); return sendPOST(url, headParam, body, resultClazz); } /** * 设置get参数 * * @param url 请求地址 * @param param 请求参数 * @return 参数拼接结果 */ private static String setGetParam(String url, Map param) { if (param != null && param.size() > 0) { StringBuilder builder = new StringBuilder(); for (String key : param.keySet()) { builder.append(key).append("=").append(param.get(key)).append("&"); } url = url + "?" + builder.toString().substring(0, builder.length() - 1); } return url; } /** * get请求 * * @param url 请求路径 * @param headParam 头部参数 * @param param 请求参数 * @return 请求结果 * @throws RequestException 请求时出现例外 */ public static T sendGET(String url, Map headParam, Map param, Class resultClazz) throws RequestException { Request request = setHeadParam(new Builder().url(setGetParam(url, param)).get(), headParam).build(); return packagingResult(request, resultClazz); } /** * 上传多张图片及参数 * * @param reqUrl URL地址 * @param headParam 头部参数 * @param params 额外参数 * @param picKey 上传图片的关键字 * @param files 图片路径 */ public static T sendPostMultipart(String reqUrl, Map headParam, Map params, String picKey, List files, Class resultClazz) throws RequestException { MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder(); multipartBodyBuilder.setType(MultipartBody.FORM); setPostParam(params, multipartBodyBuilder); // 遍历files中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key if (files != null) { for (File file : files) { String sux = getMimeType(file.getName()); MediaType mediaType = MediaType.parse(MIME.getMimeType(sux)); multipartBodyBuilder.addFormDataPart(picKey, file.getName(), RequestBody.create(mediaType, file)); } } Request request = setHeadParam(new Builder().url(reqUrl).post(multipartBodyBuilder.build()), headParam).build(); return packagingResult(request, resultClazz); } /** * 获取文件类型 * * @param fileName 文件名称 * @return 文件后缀 */ private static String getMimeType(String fileName) { return fileName.substring(fileName.lastIndexOf(".") + 1); } }