RestTemplate--SpringCloud 二:

一. 什麼是RestTemplate

優雅的HTTP請求:
傳統狀況下在java代碼裏訪問restful服務,通常使用Apache的HttpClient。不過此種方法使用起來太過繁瑣。
spring提供了一種簡單便捷的模板類來進行操做,這就是RestTemplate。

二.一個簡單的例子。

定義一個簡單的restful接口
@RestControllerpublic class TestController
{
    @RequestMapping(value = "testPost", method = RequestMethod.POST)
    public ResponseBean testPost(@RequestBody RequestBean requestBean)
    {
        ResponseBean responseBean = new ResponseBean();
        responseBean.setRetCode("0000");
        responseBean.setRetMsg("succ");
        return responseBean;
    }}
 
使用RestTemplate訪問該服務
//請求地址
        String url = "http://localhost:8080/testPost";
        //入參
        RequestBean requestBean = new RequestBean();
        requestBean.setTest1("1");
        requestBean.setTest2("2");
        requestBean.setTest3("3");
        RestTemplate restTemplate = new RestTemplate();
        ResponseBean responseBean = restTemplate.postForObject(url, requestBean, ResponseBean.class);
 
 
從這個例子能夠看出,使用restTemplate訪問restful接口很是的 簡單粗暴無腦。(url, requestMap, ResponseBean.class)這三個參數分別表明 請求地址、請求參數、HTTP響應轉換被轉換成的對象類型。
RestTemplate方法的名稱遵循命名約定,第一部分指出正在調用什麼HTTP方法,第二部分指示返回的內容。本例中調用了restTemplate.postForObject方法,post指調用了HTTP的post方法,Object指將HTTP響應轉換爲您選擇的 對象類型。還有其餘不少相似的方法,有興趣的同窗能夠 參考官方api
以上demo做者:白駒過隙_突然而已
 

3、SpringCloud中RestTemplate的用法:

 
繼續上篇:Eureka
 
現有兩個服務提供端:8001;8002 ,服務名字都是CLOUD_PAYMENT_SERVICE
服務調用端在調用的時候,須要進行負載均衡,經過輪詢,隨機等方式對服務提供方進行調用
80Controller層
 
// 直接服務提供方的服務的名字
public static final String PAY_URL="http://CLOUD-PAYMENT-SERVICE";
@Resource
public RestTemplate restTemplate;
 
 
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){
    return restTemplate.getForObject(PAY_URL+"/payment/get/"+id,CommonResult.class);
}
PS:下段代碼須要參考Springbean注入、配置方式
工具類: RestTemplate定義爲bean;這樣在@Resource的時候才能注入Controller層的類
@Configuration
public class ApplicationContextConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate(){
      return  new RestTemplate();
    }
}
SpringCloud-common包提供的註解 : @LoadBalanced 能夠實現輪序調用不一樣的服務提供服務
模擬輪詢的底層實現:
經過原子類+CAS實現
public interface LoadBalancer {
    /*
     * 一、自旋,CAS進行獲取,請求的次數
    * 二、請求的次數 % 根據服務的個數= 求餘數,獲取輪詢的服務的內容serviceInstance
    * */
 
   ServiceInstance instance(List<ServiceInstance> serviceInstanceList);
 
 
}
/**
* @introduce: 輪詢
* @author: xingMeiLing
* @DATE: 2020/6/29
**/
@Component
public class MyLB implements LoadBalancer {
/*
* 一、請求的次數 % 根據服務的個數= 求餘數,獲取輪詢的服務的內容serviceInstance
* 二、自旋,CAS進行獲取,請求的次數
* */
 
// 用原子數據類型;初始化0
private AtomicInteger atomicInteger = new AtomicInteger(0);
 
 
/**
* 請求的次數 % 根據服務的個數= 求餘數 0 或 1
*
* @author xingMeiLing
* @param serviceInstanceList 獲取輪詢的服務的內容serviceInstance
* @return
*/
@Override
public ServiceInstance instance(List<ServiceInstance> serviceInstanceList) {
int index = this.getAndInCrement() % serviceInstanceList.size();
return serviceInstanceList.get(index);
}
/**
* 自旋,CAS進行獲取,請求的次數
*
* @author xingMeiLing
* @return next 請求的次數
*/
public final int getAndInCrement(){
int current;
int next;
do{
current = this. atomicInteger.get();
next = current >= 2147483647 ? 0: current +1;
}while (!this.atomicInteger.compareAndSet(current,next));
System.out.println("次數" + next);
return next;
}
}
 
80主啓動類上:
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
public class OrderMain80 {
    public static void main(String[] args) {
        SpringApplication.run(OrderMain80.class,args);
    }
}
RibbonClient註解是Eureka實現的
服務發現的註解@EnableDiscoverClient (在啓動類上配置)
80Controller類:
@Resource
public RestTemplate restTemplate;
@Resource
private DiscoveryClient discoveryClient;
@Resource
private LoadBalancer loadBalancer;
@GetMapping("/consumer/payment/lb")
public String getPaymentLB(){
      //  獲取服務提供方;服務發現類: DiscoveryClient 是springcloud-common包下的用來查詢服務的類
    List<ServiceInstance> serviceInstances  = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
    if(serviceInstances == null || serviceInstances.size() <=0){
        return null;
    }
    ServiceInstance serviceInstance = loadBalancer.instance(serviceInstances);
    URI uri = serviceInstance.getUri();
    return restTemplate.getForObject(uri+"/payment/lb",String.class);
}
相關文章
相關標籤/搜索