與httpClient相比,okhttp能夠進行異步請求,固然也能進行同步請求,兩相比較,推薦使用okhttp,httpClient 使用參考java
四個工具類(其實只用一個工具類便可,就是①)git
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); } }
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; } }
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()); } }
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/github