与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;
}
}