一般调用第三方可以采用,httpclient resttemplete feign
话不多说直接上代码,我采用的是feign ,因为本身项目就是cloud架构,就存在服务直接的feign调用,为了同一,这次第三方调用也采用feign
@FeignClient(url="https://121.37.197.19",name = "cloudUserFeignClient", fallback = CloudUserFeignFallback.class,configuration = HoloFeignConfig.class)
public interface CloudUserFeignClient {
@PostMapping("/v1/{user_id}/enterprises/access-token")
Map verificationAccessToken(@PathVariable("user_id") String cloudUserId, @RequestBody AkSkBo akSkBo);
@GetMapping(value = "/v1/{user_id}/devices")
Map queryDevices(@RequestHeader("Access-Token") String accessToken,@PathVariable("user_id") String cloudUserId);
@GetMapping("/v1/{user_id}/channels")
Map queryChannels(@RequestHeader("Access-Token") String accessToken,@PathVariable("user_id")String cloudUserId,
@RequestParam("device_id") String device_id,@RequestParam("limit") Integer limit);
@PostMapping("/v1/{user_id}/devices/holosens")
Response cloudDeviceHolosens(@RequestHeader("Access-Token") String accessToken,@PathVariable("user_id") String cloudUserId,
@RequestBody CloudDeviceHoloAddBo cloudDeviceHoloAddBo);
@PostMapping("/v1/{user_id}/devices/gb/batch-add")
Map cloudGBBatchAdd(@RequestHeader("Access-Token") String accessToken,@PathVariable("user_id") String cloudUserId,
@RequestBody CloudDeviceGbAddBo cloudDeviceGbAddBo);
@GetMapping("/v1/{user_id}/channels")
Map queryPageChannels(@RequestHeader("Access-Token") String accessToken,@PathVariable("user_id")String cloudUserId,
@RequestParam("offset") Integer offset,@RequestParam("limit") Integer limit);
}
重点在 @FeignClient(url="https://121.37.197.19",name = "cloudUserFeignClient", fallback = CloudUserFeignFallback.class,configuration = HoloFeignConfig.class)
feign中有个属性url 为第三方的请求路径 的ip,然后 name 任意(但不能为空),fallback 为熔断处理,configuration 为对所有feign的配置(同包下生效)
重点在configuration 由于,此次请求中为https,而我们项目是没有https证书验证的,所以要跳过,该配置类中主要做的就是打印feign请求日志,其次就是 跳过https证书验证
@Slf4j
@Configuration
public class HoloFeignConfig {
// 打印feign日志
@Bean
Logger.Level deviceSendCmdFeignLoggerLevel() {
return Logger.Level.FULL;
}
@Bean
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory) throws NoSuchAlgorithmException, KeyManagementException {
SSLContext ctx = SSLContext.getInstance("SSL");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
return new LoadBalancerFeignClient(new Client.Default(ctx.getSocketFactory(),
new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
// TODO Auto-generated method stub
return true;
}
}),
cachingFactory, clientFactory);
}
}
很匆忙,后续完善
configuration = HoloFeignConfig.class 其中fegin中 这段代码就是用来标记该feign的配置类,而且,同个包下,配置类应该唯一。且此时项目日志级别应该为debug级别.
fallback = CloudUserFeignFallback.class 这段代码为配置feign的熔断,当在使用 上段代码打印日志的时候,应该屏蔽掉这段.
在HoloFeignConfig 配置类中还可以插入下面的代码,来处调用feign时,直接报错的拦截,自定返回异常
@Bean
public ErrorDecoder errorDecoder(){
return new ErrorDecoder() {
@Override
public Exception decode(String methodKey, Response response) {
try {
InputStream inputStream = response.body().asInputStream();
JSONObject jsonObject = JSONUtil.parseObj(String.valueOf(IoUtil.read(inputStream)));
inputStream.close();
return new MixException(7909, (String) jsonObject.get("error_msg"));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
}
至此,feign调用的各种处理已经基本实现了较为清晰的日志功能,方便找错误,实现了自定以的错误返回,相对完善.