okhttp 实现异步请求

与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/

转载于:https://my.oschina.net/u/3574106/blog/3060461

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值