文档章节

okhttp 实现异步请求

暗中观察
 暗中观察
发布于 06/10 23:21
字数 811
阅读 23
收藏 0

与httpClient相比,okhttp可以进行异步请求,当然也能进行同步请求,两相比较,推荐使用okhttp,httpClient 使用参考

四个工具类(其实只用一个工具类即可,就是①)

①,OKHttpUtil

import com.alibaba.fastjson.JSON;
import okhttp3.*;
import okhttp3.Request.Builder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

public class OKHttpUtil {

  private OKHttpUtil() {}
  private static final Logger LOGGER = LoggerFactory.getLogger(OKHttpUtil.class);
  private static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
  private static OkHttpClient httpClient = new OkHttpClient().newBuilder().readTimeout(10,TimeUnit.SECONDS).build();


  /**
   * 提交json请求
   * @param url
   * @param conent
   * @return
   */
  public static String executeJson(String url,Object conent) {
    return executeJson(url,conent,null);
  }

  public static String executeJson(String url,Object conent, Map<String, String> headers) {
    Builder builder = getBuilder(url,headers);
    String reqParams=null;
    if(conent instanceof String){
      reqParams = conent.toString();
    }else{
      reqParams=JSON.toJSONString(conent);
    }
    RequestBody requestBody = RequestBody.create(JSON_TYPE, reqParams);
    builder.post(requestBody);
    return execute(url,builder);
  }

  /**
   * 提交表单请求
   * @param url
   * @param paramMap
   * @param headers
   * @return
   * @throws IOException
   */
  public static String executeForm(String url, Map<String, String> paramMap, Map<String, String> headers) {
    Builder builder = getBuilder(url,headers);
    FormBody.Builder formBuilder = new FormBody.Builder();
    for (Map.Entry<String,String> entry:paramMap.entrySet()) {
      formBuilder.add(entry.getKey(),entry.getValue());
    }
    builder.post(formBuilder.build());
    return execute(url,builder);

  }

  /**
   * get 请求
   * @param url
   * @return
   */
  public static String get(String url) {
    return get(url,null);
  }
  public static String get(String url,Map<String, String> headers){
    Builder builder = getBuilder(url,headers);
    return execute(url,builder);
  }

  private static String execute(String url, Builder builder) {
    String result = null;
    long startTime = System.currentTimeMillis();
    Call call = httpClient.newCall(builder.build());
    try (Response response  = call.execute()){
      result=response.body().string();
    } catch (IOException e) {
      LOGGER.error("okhttp happen error",e);
    }
    LOGGER.info("okhttp url {} cost {} ms",url,System.currentTimeMillis()-startTime);
    return result;
  }

  private static Builder getBuilder(String url,Map<String, String> headers){
    Builder builder = new Builder().url(url);
    if(headers != null && !headers.isEmpty()) {
      for(String key : headers.keySet()) {
         builder.addHeader(key, headers.get(key));
      }
    }
    return builder;
  }

  public void enqueue(String url, Callback callBack) {
    enqueue(url, callBack, null);
  }

  public void enqueue(String url,Callback callBack, Map<String, String> headers) {
    Builder builder = getBuilder(url, headers);
    Call call = httpClient.newCall(builder.build());
    call.enqueue(callBack);
  }

}

② HttpCallback

public class HttpCallback implements Callback {
  private static Logger log = LoggerFactory.getLogger("netLog");

  private int successEventType;
  private int failureEventType;
  private long itemId;

  @Override
  public void onFailure(Call call, IOException e) {
    log.error("send http request fail. offer id {}, url {}", itemId, call.request().url().toString());
    log.error("send http request fail reason !", e);
//    EventBus.getInstance().push(failureEventType, itemId, null);
    HttpCallBackPool.getInstance().release(this);
  }

  @Override
  public void onResponse(Call call, Response response) throws IOException {
    HttpResponse httpResponse = buildHttpResponse(response);
//    EventBus.getInstance().push(successEventType, itemId, httpResponse);
    HttpCallBackPool.getInstance().release(this);
  }

  private HttpResponse buildHttpResponse(Response response) {
    HttpResponse httpResponse = new HttpResponse();
    httpResponse.setRequest(response.request());
    httpResponse.setCode(response.code());
    httpResponse.setLocation(response.header("Location"));
    httpResponse.setContentType(response.body().contentType());
    httpResponse.setRefresh(response.header("Refresh"));
    try {
      httpResponse.setBody(response.body().string());
    } catch (IOException e) {
      log.error("get response body fail. url: {}", response.request().url().toString());
      httpResponse.setBody("");
    }
    return httpResponse;
  }

  public void setItemId(long itemId) {
    this.itemId = itemId;
  }

  public void setSuccessEventType(int successEventType) {
    this.successEventType = successEventType;
  }

  public void setFailureEventType(int failureEventType) {
    this.failureEventType = failureEventType;
  }
}

③,HttpCallBackPool

public class HttpCallBackPool {
  private static HttpCallBackPool instance = new HttpCallBackPool();
  private static Logger log = LoggerFactory.getLogger(HttpCallBackPool.class);

  private Queue<HttpCallback> inactive = new LinkedList<>();

  private HttpCallBackPool() {
  }

  public static HttpCallBackPool getInstance() {
    return instance;
  }

  /**
   * 获取一个HttpCallBack
   *
   * @return
   */
  public HttpCallback allocate(long itemId, int successEventType, int failureEventType) {
    HttpCallback httpCallback = inactive.poll();
    if (httpCallback == null) {
      httpCallback = new HttpCallback();
    }
    httpCallback.setItemId(itemId);
    httpCallback.setSuccessEventType(successEventType);
    httpCallback.setFailureEventType(failureEventType);
    return httpCallback;
  }

  /**
   * 释放HttpCallBack
   *
   * @param
   */
  public void release(HttpCallback httpCallback) {
//    httpCallback.setItemId(EventBus.INVALID_ITEM_ID);
    inactive.add(httpCallback);
    log.info("httpCallbackPool size: {}", inactive.size());
  }

}

④,HttpResponse

public class HttpResponse {
  /**
   * 该response对应的request
   */
  private Request request;

  /**
   * 返回的状态码
   */
  private int code;

  /**
   * 跳转链接
   */
  private String location;

  /**
   * 返回的类型
   */
  private MediaType contentType;

  /**
   * 返回的内容
   */
  private String body;

  /**
   * Refresh头部内容
   */
  private String refresh;

  public String getRefresh() {
    return refresh;
  }

  public void setRefresh(String refresh) {
    this.refresh = refresh;
  }

  public Request getRequest() {
    return request;
  }

  public void setRequest(Request request) {
    this.request = request;
  }

  public int getCode() {
    return code;
  }

  public void setCode(int code) {
    this.code = code;
  }

  public boolean isRedirect() {
    switch (code) {
      case HTTP_PERM_REDIRECT:
      case HTTP_TEMP_REDIRECT:
      case HTTP_MULT_CHOICE:
      case HTTP_MOVED_PERM:
      case HTTP_MOVED_TEMP:
      case HTTP_SEE_OTHER:
        return true;
      default:
        return false;
    }
  }

  public boolean isSuccessful() {
    return code >= 200 && code < 400;
  }

  public String getLocation() {
    return location;
  }

  public void setLocation(String location) {
    this.location = location;
  }

  public MediaType getContentType() {
    return contentType;
  }

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

  public String getBody() {
    return body;
  }

  public void setBody(String body) {
    this.body = body;
  }
}

官方文档:https://square.github.io/okhttp/

© 著作权归作者所有

暗中观察

暗中观察

粉丝 7
博文 128
码字总数 45846
作品 0
惠州
私信 提问
Android 网络框架 OKHttp

概述 OKhttp是一个网络请求开源项目,Android网络请求轻量级框架,支持文件上传与下载,支持https,由移动支付Square公司贡献。 依赖 compile 'com.squareup.okhttp3:okhttp:3.8.1' Get请求 ...

xi阳
2018/09/04
0
0
Android okhttp3.0 框架使用总结

最近工作主要用到OkHttp3.0网络请求框架,进行Get请求,Post请求,多文件上传等功能,本文内容大部分来源于网上博文,仅做个人总结记录 以下内容来源其他博文: 在使用OKHttp之前,首先要先了...

某杰
2018/09/28
0
0
OkHttp 文档翻译之 Calls

Calls Http client 的工作是接收请求和生成响应。这个在原理上很简答的问题,在实现时变得很棘手。 Requests 每个 Http request 包含一个 URL,一个方法(例如 :GET or Post),和 Headers ...

黑泥卡
2018/08/21
0
0
Android技能树 — 网络小结之 OkHttp超超超超超超超详细解析

前言: 本文也做了一次标题党,哈哈,其实写的还是很水,各位原谅我O(∩_∩)O。 介于自己的网络方面知识烂的一塌糊涂,所以准备写相关网络的文章,但是考虑全部写在一篇太长了,所以分开写,...

青蛙要fly
2018/11/13
0
0
OkHttp 4.0.0 RC 3 发布,从 Java 切换到 Kotlin

OkHttp 4.0.0 RC 3 发布了,此版本修复了一个问题,在 okhttp3.internal.HttpMethod 中保留二进制兼容性。 OkHttp 是一个适用于 Android 和 Java 应用的 HTTP 和 HTTP/2 客户端,它的使用非常...

h4cd
06/26
8.9K
34

没有更多内容

加载失败,请刷新页面

加载更多

只需一步,在Spring Boot中统一Restful API返回值格式与统一处理异常

统一返回值 在前后端分离大行其道的今天,有一个统一的返回值格式不仅能使我们的接口看起来更漂亮,而且还可以使前端可以统一处理很多东西,避免很多问题的产生。 比较通用的返回值格式如下:...

晓月寒丶
昨天
59
0
区块链应用到供应链上的好处和实际案例

区块链可以解决供应链中的很多问题,例如记录以及追踪产品。那么使用区块链应用到各产品供应链上到底有什么好处?猎头悬赏平台解优人才网小编给大家做个简单的分享: 使用区块链的最突出的优...

猎头悬赏平台
昨天
28
0
全世界到底有多少软件开发人员?

埃文斯数据公司(Evans Data Corporation) 2019 最新的统计数据(原文)显示,2018 年全球共有 2300 万软件开发人员,预计到 2019 年底这个数字将达到 2640万,到 2023 年达到 2770万。 而来自...

红薯
昨天
65
0
Go 语言基础—— 通道(channel)

通过通信来共享内存(Java是通过共享内存来通信的) 定义 func service() string {time.Sleep(time.Millisecond * 50)return "Done"}func AsyncService() chan string {retCh := mak......

刘一草
昨天
58
0
Apache Flink 零基础入门(一):基础概念解析

Apache Flink 的定义、架构及原理 Apache Flink 是一个分布式大数据处理引擎,可对有限数据流和无限数据流进行有状态或无状态的计算,能够部署在各种集群环境,对各种规模大小的数据进行快速...

Vincent-Duan
昨天
60
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部