1.介绍
feign、http,有时候在调用第三方api的时候、使用httpclient,别人的接口不可能提供它的配置,自己项目框架是spring的,使用feign相互配置,都是okhttpclient的方式。Feign是一个接口声明式调用框架,实现了一个抽象层的逻辑,没有真正实现底层http请求,提供了一个client接口用于实现底层http操作,默认提供的实现是基于httpurlconnection,也有基于apachehttpclient的实现,且feign具有分布式负载均衡功能。
2.案例
需求是在本服务中调用另外一个服务中的设备上线的功能,有feign、http等可以选择,这里选择的是http调用。
首先引入pom文件
<!--Hutool工具包-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.6</version>
</dependency>
<!--重试架构-->
<dependency>
<groupId>com.github.rholder</groupId>
<artifactId>guava-retrying</artifactId>
<version>2.0.0</version>
</dependency>
编写httpUtils类
package com.zhy.utils;
import cn.hutool.http.HttpRequest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.rholder.retry.*;
import com.google.common.base.Predicates;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
import java.util.concurrent.*;
@Slf4j
public class HttpUtils{
private static final String CONTENT_TYPE = "Content-Type";
private static final String AUTHORIZATION = "Authorization";
private static final String CONTENT_TYPE_VALUE = "application/x-www-form-urlencoded";
private static final String CONTENT_TYPE_VALUE_JSON = "application/json";
private static ObjectMapper json = new ObjectMapper();
private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
//重试间隔
private static long sleepTime = 1L;
//重试次数
private static int attemptNumber = 5;
//设置重试机制
private final static Retryer<String> retryer = RetryerBuilder.<String>newBuilder()
// 设置自定义段元重试源
.retryIfResult(Predicates.<String>isNull())
// 设置异常重试源
.retryIfExceptionOfType(Exception.class)
// 设置异常重试源
.retryIfRuntimeException()
// 设置重试次数
.withStopStrategy(StopStrategies.stopAfterAttempt(attemptNumber))
// 设置每次重试间隔
.withWaitStrategy(WaitStrategies.fixedWait(sleepTime, TimeUnit.SECONDS))
.build();
/**
* 设备上线使用
* @param url
* @param paramMap
* @param timeout
*/
public static void deviceOnline(String url, Map<String, Object> paramMap, int timeout) {
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
postByRetry(url,null,1);
}
});
}
/**
*
* @param url 访问路径
* @param paramMap 请求体
* @param timeout 超时时间 单位: 秒
* @return
* @throws JsonProcessingException
*/
public static String postByRetry(String url, Map<String, Object> paramMap, int timeout) {
Callable<String> task = new Callable<String>() {
int i = 0;
@Override
public String call() throws Exception {
i++;
if(i > 1){
log.info("请求初次执行失败,开始第{}次执行!", i);
}
String result = post(url, paramMap, timeout);
return result;
}
};
String res = "";
try {
//执行任务的重试,得到返回结果
res = retryer.call(task);
} catch (ExecutionException e) {
log.error("Post ExecutionException", e);
} catch (RetryException e) {
log.error("Post RetryException", e);
}
return res;
}
/**
*
* @param url 访问路径
* @param paramMap 请求体
* @param timeout 超时时间 单位: 秒
* @return
* @throws JsonProcessingException
*/
public static String post(String url, Map<String, Object> paramMap, int timeout) throws JsonProcessingException {
String map = json.writeValueAsString(paramMap);
String result = HttpRequest
.post(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE).timeout(timeout * 1000)
.body(map).execute().body();
return result;
}
/**
*
* @param url 访问路径
* @param map 请求体
* @param timeout 超时时间 单位: 秒
* @return
*/
public static String post(String url, String map, int timeout) {
String result = HttpRequest
.post(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE).timeout(timeout * 1000)
.body(map).execute().body();
return result;
}
/**
*
* @param url 访问路径
* @param map 请求体
* @param timeout 超时时间 单位: 秒
* @return
*/
public static String post(String url, String map, int timeout,String authorization) {
String result = HttpRequest
.post(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE).header(AUTHORIZATION,authorization)
.timeout(timeout * 1000)
.body(map).execute().body();
return result;
}
/**
*
* @param url 访问路径
* @param timeout 超时时间 单位: 秒
* @param authorization 认证token
*/
public static String get(String url, int timeout,String authorization) {
String result = HttpRequest.get(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE_JSON).header(AUTHORIZATION,authorization)
.timeout(timeout * 1000).execute().body();
return result;
}
/**
*
* @param url 访问路径
* @param timeout 超时时间 单位: 秒
* @param authorization 认证token
*/
public static String delete(String url, int timeout,String authorization ,String map) {
String result = HttpRequest.delete(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE_JSON).header(AUTHORIZATION,authorization)
.timeout(timeout * 1000).body(map).execute().body();
return result;
}
/**
*
* @param url 访问路径
* @param timeout 超时时间 单位: 秒
* @param authorization 认证token
*/
public static String delete(String url, int timeout,String authorization ) {
String result = HttpRequest.delete(url).header(CONTENT_TYPE,CONTENT_TYPE_VALUE_JSON).header(AUTHORIZATION,authorization)
.timeout(timeout * 1000).execute().body();
return result;
}
}
这里的publishConnectEd(clientid,userName);使用http远程调用另外一个服务中的设备上线的接口。
String url : 需要跳转的接口路径。(如:http://localhost/user/login)
param: 远程调用时,所需参数。
HttpUtils.postByRetry() 实现http远程调用。