SpringBoot Http远程调用
ItDylan 人气:0一、在实现远程调用时可以使用feign与http远程调用,两者的关系有一下几点:
feign、http,有时候在调用第三方api的时候、使用httpclient,别人的接口不可能提供它的配置,自己项目框架是spring的,使用feign相互配置,都是okhttpclient的方式。Feign是一个接口声明式调用框架,实现了一个抽象层的逻辑,没有真正实现底层http请求,提供了一个client接口用于实现底层http操作,默认提供的实现是基于httpurlconnection,也有基于apachehttpclient的实现,且feign具有分布式负载均衡功能。
二、使用案例
需求是在本服务中调用另外一个服务中的设备上线的功能,有feign、http等可以选择,这里选择的是http调用。
/** * 超级管理员授权 * @param userName * @param clientid * @return */ @PostMapping("/mqtt/superuser") @Transactional public Integer loginCheck2(@RequestParam("username") String userName, @RequestParam("clientid") String clientid){ System.out.println(userName); System.out.println("超级管理员"); userName = "6217XXXXXXXXXXXd85/3XXXX3"; //拼接实体类跳转ibms-iot平台,上线 publishConnected(clientid, userName); return 400; }
/** * 远程调用另一个服务中的设备上线功能 * @param clientid * @param userName */ private void publishConnected(String clientid, String userName) { Connected connected = new Connected(); connected.setAction(ACTION); connected.setClientid(clientid); connected.setUsername(userName); Date date = new Date(); connected.setConnected_at(date.getTime()); Map<String, Object> param = BeanUtil.beanToMap(connected, false, true); String url = IotPropertiesConfig.HTTP_PREFIX + IotPropertiesConfig.IP_PORT+ UrlConstant.webHook_path; String result = HttpUtils.postByRetry(url, param, IotPropertiesConfig.HTTP_TIMEOUT); log.info("设备:{}上线内容的通知结果:{}",connected.getUsername(),result); }
httpUtil工具类:
package com.setch.crodigy.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("",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:8080/user/login)
param: 远程调用时,所需参数。
HttpUtils.postByRetry() 实现http远程调用。
下面是需要被远程调用的接口
import antlr.StringUtils; import com.setch.crodigy.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; @RequestMapping("/testDemo") @RestController public class ProductController { @Autowired private ProductService productService; @PostMapping("/save") @Transactional public boolean saveProduct(@RequestBody Product product){ Product result = productService.save(product); if (result != null){ return true; }else { return false; } } }
以上是本人个人使用案例,测试成功,初次使用,若有问题欢迎大家提出指正。
希望对大家的学习有所帮助,也希望大家多多支持。
加载全部内容