在接口请求的时候我们一般都是一次请求,成功就是成功失败就是失败,但是有的时候我们要同步的确定接口请求成功,比如一个订单的状态,订单状态对整个流程影响是很大的,所以我们在有必要的时候需要同步请求成功,所以我们就需要多次请求接口直到成功或者直到N次的请求,所以我们可以看看下面demo来实现三次请求。
代码如下:
import com.alibaba.fastjson.JSON;
import com.google.gson.reflect.TypeToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* @author wanghaidong
* @data 2017/11/29
*/
@Service("reassignOrderService")
public class ReassignOrderServiceImpl implements IReassignOrderService {
Logger logger = LoggerFactory.getLogger(ReassignOrderServiceImpl.class);
private static final String ORDER_STATUS_URL = "/reassign";
/**
* 最大尝试次数
*/
private final static int MAX_RETRY = 3;
/**
* 线程池
*/
private volatile StandardThreadExecutor executor = null;
/**
* 线程池初始化
*/
private void init() {
if (null == executor) {
synchronized (logger) {
if (null == executor) {
executor = new StandardThreadExecutor(20, 50, 1, TimeUnit.MINUTES, 20000, new NameThreadFactory("orderPool-query-reassign-status"));
executor.allowCoreThreadTimeOut(true);
}
}
}
}
/**
* 钩子,关闭线程池
*/
@PreDestroy
private void destroy() {
if (executor != null) {
executor.shutdown();
}
}
@Override
public int orderReassignStatus(String orderNo) {
if (null == executor) {
init();
}
String ip = "xxx";
String url = new StringBuilder(ip).append(ReassignOrderServiceImpl.ORDER_STATUS_URL).toString();
Map<String, Object> params = new HashMap<>(1);
params.put("orderNo", orderNo);
logger.info("请求url:{},请求参数param:{}", url, params);
long beginTime = System.currentTimeMillis();
String res;
ResponseResult<?> responseResult;
for (int i = 0; i < ReassignOrderServiceImpl.MAX_RETRY; i++) {
res = this.executeQuery(url, params);
logger.info("请求返回结果res:{},接口耗时times:{}ms,尝试请求次数tryTimes:{}", res, (System.currentTimeMillis() - beginTime), i);
try {
if (null == res) {
continue;
} else {
responseResult = GsonUtils.jsonToBean(res, new TypeToken<ResponseResult<Object>>() {
}.getType());
int code = (null == responseResult ? ResponseCodeEnum.RESPONSE_FAILD.getCode() : responseResult.getCode());
if (code == ResponseCodeEnum.RESPONSE_FAILD.getCode()) {
continue;
}
boolean statusFlag = (code == ResponseCodeEnum.RESPONSE_SUCCESS.getCode() && (null != responseResult.getData() && null != responseResult.getData().getNewOrderNo()));
if (statusFlag) {
return ReassignOrderEnum.REASSIGN_ORDER.getCode();
} else {
return ReassignOrderEnum.NOT_REASSIGN_ORDER.getCode();
}
}
} catch (Exception e) {
logger.error("请求耗时times:{}ms", (System.currentTimeMillis() - beginTime), e);
}
}
return ReassignOrderEnum.FAIL.getCode();
}
/**
* 请求执行方法
*
* @param url
* @param params
* @return
*/
private String executeQuery(String url, Map<String, Object> params) {
String res = null;
Future<String> result = this.executor.submit(new Callable<String>() {
@Override
public String call() {
String res = HttpUtil.getIntance().post(url, params);
return res;
}
});
boolean flag = false;
while (!flag) {
try {
if (result.isDone()) {
flag = true;
res = result.get();
}
} catch (Exception e) {
logger.error("改派状态", e);
break;
}
}
return res;
}
}
在平时我们会用到多次请求接口的方式,虽然上面的代码不是最好的实现方式,但是思路应该是类似的!