基于OkHttp网络通信工具类(发送get、post请求、文件上传和下载)

一、为什么要用OkHttp?


okhttp是专注于提升网络连接效率的http客户端。
优点:

1、它能实现同一ip和端口的请求重用一个socket,这种方式能大大降低网络连接的时间,和每次请求都建立socket,再断开socket的方式相比,降低了服务器服务器的压力。

2、okhttp 对http和https都有良好的支持。

3、okhttp 不用担心android版本变换的困扰。

4、成熟的网络请求解决方案,比HttpURLConnection更好用。
5、支持异步发送网络请求,响应可在线程处理。



二、其它的网络通信框架:


1、HttpURLConnection:java.util包下的http客户端,对网络请求的封装没有HttpClient那么彻底,api使用起来比较简单,易于扩展。
2、HttpClient:Apache的一个第三方网络框架,api众多,用起来比较方便,实现比较稳定,但不易于扩展。
3、Volley:google推出的网络通信框架,适合处理数据量小、通信频繁的网络操作,内部封装了异步线程,不适合大数据量的请求。


下面对OkHttp做了一个简单的封装,可用于发送get、post请求(支持请求参数格式为键值对、json格式)、文件上传、文件下载。


package com.universe.thirdparty.okhttp;

import java.io.IOException;
import java.nio.charset.Charset;
import java.time.Duration;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import com.alibaba.fastjson.JSONObject;
import com.universe.thirdparty.fastjson.CollectionUtils;

import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class OkHttpUtils {

  public static final MediaType JSON = MediaType.get("application/json;charset=utf-8");
  public static final MediaType OCTET_STREAM = MediaType.get("application/octet-stream");
  /**
   * 超时、读、写时长
   */
  private static final long TIMEOUT_MILLIS = 2000;

  private static final Builder DEFAULT_CLIENT_BUILDER = new OkHttpClient.Builder();

  static {
    DEFAULT_CLIENT_BUILDER.readTimeout(Duration.ofMillis(TIMEOUT_MILLIS));
    DEFAULT_CLIENT_BUILDER.writeTimeout(Duration.ofMillis(TIMEOUT_MILLIS));
    DEFAULT_CLIENT_BUILDER.connectTimeout(Duration.ofMillis(TIMEOUT_MILLIS));
  }

  public static OkHttpClient getOkHttpClient() {
    return DEFAULT_CLIENT_BUILDER.build();
  }

  public static synchronized OkHttpClient getOkHttpClient(long timeoutInMillis) {
    DEFAULT_CLIENT_BUILDER.readTimeout(Duration.ofMillis(timeoutInMillis));
    DEFAULT_CLIENT_BUILDER.writeTimeout(Duration.ofMillis(timeoutInMillis));
    DEFAULT_CLIENT_BUILDER.connectTimeout(Duration.ofMillis(timeoutInMillis));
    return DEFAULT_CLIENT_BUILDER.build();
  }

  public static OkHttpResp sendGet(String url, Map<String, Object> reqHeaders, Map<String, Object> params) throws IOException {
    return sendGet(url, reqHeaders, params, TIMEOUT_MILLIS);
  }

  public static OkHttpResp sendGet(String url, Map<String, Object> reqHeaders, Map<String, Object> params, long timeoutInMillis)
      throws IOException {
    OkHttpClient client = getOkHttpClient(timeoutInMillis);
    HttpUrl.Builder urlBuilder = HttpUrl.get(url).newBuilder();
    // 拼接参数
    if (!CollectionUtils.isEmpty(params)) {
      params.forEach((key, value) -> {
        urlBuilder.addEncodedQueryParameter(key, String.valueOf(value));
      });
    }

    HttpUrl httpUrl = urlBuilder.build();
    Request.Builder reqBuilder = new Request.Builder().url(httpUrl);
    addHeaders(reqHeaders, reqBuilder);
    Request request = reqBuilder.get().build();

    return getResponse(client, request);
  }

  public static OkHttpResp sendPostInHtmlForm(String url, Map<String, Object> headers, Map<String, Object> params) throws IOException {
    return sendPostInHtmlForm(url, headers, params, TIMEOUT_MILLIS);
  }

  public static OkHttpResp sendPostInHtmlForm(String url, Map<String, Object> reqHeaders, Map<String, Object> params, long timeoutInMillis)
      throws IOException {
    OkHttpClient client = getOkHttpClient(timeoutInMillis);
    Request.Builder reqBuilder = new Request.Builder().url(url);
    addHeaders(reqHeaders, reqBuilder);

    FormBody.Builder formBuilder = new FormBody.Builder(Charset.forName("UTF-8"));
    FormBody formBody = formBuilder.build();

    if (!CollectionUtils.isEmpty(params)) {
      params.forEach((paramName, paramValue) -> {
        formBuilder.add(paramName, String.valueOf(paramValue));
      });
    }

    Request request = reqBuilder.post(formBody).build();
    return getResponse(client, request);
  }

  public static OkHttpResp sendPostInJsonFormat(String url, Map<String, Object> reqHeaders, Map<String, Object> params) throws IOException {
    return sendPostInJsonFormat(url, reqHeaders, params, TIMEOUT_MILLIS);
  }

  public static OkHttpResp sendPostInJsonFormat(String url, Map<String, Object> reqHeaders, Map<String, Object> params,
      long timeoutInMillis) throws IOException {
    OkHttpClient client = getOkHttpClient(timeoutInMillis);
    Request.Builder reqBuilder = new Request.Builder().url(url);
    addHeaders(reqHeaders, reqBuilder);

    RequestBody requestBody = RequestBody.create(JSON, JSONObject.toJSONString(params));
    Request request = reqBuilder.post(requestBody).build();

    return getResponse(client, request);
  }

  public static OkHttpResp uploadFile(String url, List<MultipartFile> files) throws IOException {
    return uploadFile(url, files, TIMEOUT_MILLIS);
  }

  public static OkHttpResp uploadFile(String url, List<MultipartFile> files, long timeoutInMillis) throws IOException {
    OkHttpClient client = getOkHttpClient(timeoutInMillis);
    MultipartBody.Builder multiBuilder = new MultipartBody.Builder();
    multiBuilder.setType(MultipartBody.FORM);
    if (!CollectionUtils.isEmpty(files)) {
      files.forEach(multipartFile -> {
        String fieldName = multipartFile.getFieldName();
        String fileName = multipartFile.getFileName();
        byte[] content = multipartFile.getContent();
        multiBuilder.addFormDataPart(fieldName, fileName, RequestBody.create(OCTET_STREAM, content));
      });
    }

    MultipartBody requestBody = multiBuilder.build();
    Request request = new Request.Builder().url(url).post(requestBody).build();
    return getResponse(client, request);
  }

  public static byte[] downloadFile(String url) throws IOException {
    return downloadFile(url, TIMEOUT_MILLIS);
  }

  public static byte[] downloadFile(String url, long timeoutInMillis) throws IOException {
    OkHttpClient client = getOkHttpClient(timeoutInMillis);
    Request request = new Request.Builder().url(url).get().build();
    try (Response response = client.newCall(request).execute()) {
      if (!response.isSuccessful()) {
        return null;
      }

      return response.body().bytes();
    } catch (IOException e) {
      throw e;
    }
  }

  private static OkHttpResp getResponse(OkHttpClient client, Request request) throws IOException {
    OkHttpResp resp = new OkHttpResp();
    // 确保Response和ResponseBody关闭
    try (Response response = client.newCall(request).execute()) {
      if (!response.isSuccessful()) {
        resp.setSuccessful(false);
      }
      ResponseBody body = response.body();
      resp.setSuccessful(true);
      resp.setRespStr(body.string());
      resp.setRespHeaders(response.headers());
      resp.setContentType(body.contentType());
      resp.setContentLength(body.contentLength());
      return resp;
    } catch (IOException e) {
      throw e;
    }
  }

  private static void addHeaders(Map<String, Object> reqHeaders, Request.Builder reqBuilder) {
    if (CollectionUtils.isEmpty(reqHeaders)) {
      return;
    }

    reqHeaders.forEach((headerName, headerValue) -> {
      reqBuilder.addHeader(headerName, String.valueOf(headerValue));
    });
  }

  public static class MultipartFile {

    /**
     * 文件域名,相当于表单中文件域名
     */
    private String fieldName;
    private String fileName;
    private byte[] content;

    public MultipartFile() {
    }

    public MultipartFile(String fieldName, String fileName, byte[] content) {
      this.fieldName = fieldName;
      this.fileName = fileName;
      this.content = content;
    }

    public String getFieldName() {
      return fieldName;
    }

    public void setFieldName(String fieldName) {
      this.fieldName = fieldName;
    }

    public String getFileName() {
      return fileName;
    }

    public void setFileName(String fileName) {
      this.fileName = fileName;
    }

    public byte[] getContent() {
      return content;
    }

    public void setContent(byte[] content) {
      this.content = content;
    }
  }

  public static class OkHttpResp {

    private String respStr;
    private Headers respHeaders;
    private MediaType contentType;
    private long contentLength;
    private boolean successful;

    public String getRespStr() {
      return respStr;
    }

    public Headers getRespHeaders() {
      return respHeaders;
    }

    public MediaType getContentType() {
      return contentType;
    }

    public long getContentLength() {
      return contentLength;
    }

    public boolean isSuccessful() {
      return successful;
    }

    public void setRespStr(String respStr) {
      this.respStr = respStr;
    }

    public void setRespHeaders(Headers respHeaders) {
      this.respHeaders = respHeaders;
    }

    public void setContentType(MediaType contentType) {
      this.contentType = contentType;
    }

    public void setContentLength(long contentLength) {
      this.contentLength = contentLength;
    }

    public void setSuccessful(boolean successful) {
      this.successful = successful;
    }

    @Override
    public String toString() {
      return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

  }
}


对阿里FastJSONj进行JavaBean到json字符串映射的简单封装。

package com.universe.thirdparty.fastjson;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializeFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;

public class JsonUtils {

  public static String toJsonString(Object obj, SerializeFilter... filters) {
    return toJsonString(obj, null, false, false, filters);
  }

  public static String toJsonStringWithNullValue(Object obj, SerializeFilter... filters) {
    return toJsonString(obj, null, true, false, filters);
  }

  public static String toPrettyJsonString(Object obj, SerializeFilter... filters) {
    return toJsonString(obj, null, false, true, filters);
  }

  public static String toPrettyJsonStringWithNullValue(Object obj, SerializeFilter... filters) {
    return toJsonString(obj, null, true, true, filters);
  }

  public static String toJsonStringWithDateFormat(Object obj, String dateFormat, SerializeFilter... filters) {
    return toJsonString(obj, dateFormat, false, false, filters);
  }

  public static String toJsonStringWithDateFormatAndNullValue(Object obj, String dateFormat, SerializeFilter... filters) {
    return toJsonString(obj, dateFormat, true, false, filters);
  }

  public static String toPrettyJsonStringWithDateFormat(Object obj, String dateFormat, SerializeFilter... filters) {
    return toJsonString(obj, dateFormat, false, true, filters);
  }

  public static String toPrettyJsonStringWithDateFormatAndNullValue(Object obj, String dateFormat, SerializeFilter... filters) {
    return toJsonString(obj, dateFormat, true, true, filters);
  }

  public static String toJsonString(Object obj, String dateFormat, boolean writeNullValue, boolean prettyFormat,
      SerializeFilter... filters) {
    if (obj == null) {
      return null;
    }

    int defaultFeature = JSON.DEFAULT_GENERATE_FEATURE;
    if (writeNullValue) {
      return prettyFormat
          ? JSON.toJSONString(obj, SerializeConfig.globalInstance, filters, dateFormat, defaultFeature, SerializerFeature.WriteMapNullValue,
              SerializerFeature.PrettyFormat)
          : JSON.toJSONString(obj, SerializeConfig.globalInstance, filters, dateFormat, defaultFeature,
              SerializerFeature.WriteMapNullValue);
    }

    return prettyFormat
        ? JSON.toJSONString(obj, SerializeConfig.globalInstance, filters, dateFormat, defaultFeature, SerializerFeature.PrettyFormat)
        : JSON.toJSONString(obj, SerializeConfig.globalInstance, filters, dateFormat, defaultFeature);

  }

  public static <T> T toJavaBean(String jsonStr, Class<T> clazz) {
    if (StringUtils.isBlank(jsonStr)) {
      return null;
    }

    return JSON.parseObject(jsonStr, clazz);
  }

  public static <T> List<T> toList(String jsonStr, Class<T> clazz) {
    if (StringUtils.isBlank(jsonStr)) {
      return null;
    }

    return JSON.parseArray(jsonStr, clazz);
  }

  public static Map<String, Object> toMap(String jsonStr) {
    if (StringUtils.isBlank(jsonStr)) {
      return null;
    }

    return JSON.parseObject(jsonStr, new TypeReference<Map<String, Object>>() {});
  }

  public static Map<String, Object> javaBeanToMap(Object obj) {
    if (Objects.isNull(obj)) {
      return null;
    }

    return toMap(toJsonString(obj));
  }

  public static <T> T mapToJavaBean(Map<String, ? extends Object> map, Class<T> clazz) {
    if (CollectionUtils.isEmpty(map)) {
      return null;
    }

    String jsonStr = JSON.toJSONString(map);
    return JSON.parseObject(jsonStr, clazz);
  }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nick说说前后端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值