1. 程式人生 > >REST(四)使用RestTemplate

REST(四)使用RestTemplate

REST(四)使用RestTemplate

在當今微服務中,會將一個大系統拆分為多個微服務系統。按微服務應用的建議,每個微服務系統都會暴露Rest風格的URI請求給別的微服務系統所呼叫。為了方便完成系統之間的相互呼叫,spring還給予了模板類RestTemplate,通過它可以很方便地對Rest請求進行系統之間的呼叫,完成系統之間的資料整合。

使用RestTemplate請求後端

RestTemplate的底層是通過類HttpURLConnection實現的。

使用RestTemplate請求後端存在多種方法,這裡只講幾種常用的。

控制器

/**
 * @Description:RestTemplate
 * @Author: lay
 * @Date: Created in 1:02 2018/11/18
 * @Modified By:IntelliJ IDEA
 */
@RestController public class RestTemplateController { private RestTemplate restTemplate=new RestTemplate(); //具體方法如下..... }

HTTP GET請求

    //使用REST Template進行HTTP get請求
    @GetMapping("/user/byId")
    public UserVo getUser(){
        Long id=1L;
        //消費服務,第一個引數為url,第二個引數是返回型別,第三個是uri路徑引數
UserVo userVo=restTemplate.getForObject("http://localhost:8080/user/{id}",UserVo.class,id); System.out.println(userVo.getUserName()); return userVo; }

這裡的getForObject方法是需要關注的核心方法

第一個引數URI標明請求伺服器什麼資源,而{id}則代表引數。

第二個引數宣告為UserVo.class,表示請求將返回UserVo類的結果,但是實際上伺服器只會返回JSON型別的資料給我們,只是RestTemplate內部會將其轉換為Java物件。

第二個引數後面則是URI中對應的引數,只是這裡只有一個引數,所以就只有一個id。實際上它是一個可變長的引數,如果URI有多個引數,只需要按照順序寫就可以了。

但是如果請求引數很多,顯然可讀性就不是那麼好了,spring已經考慮了這個問題。下面對於使用者進行查詢,這裡設計使用者名稱稱(userName) ,備註(note),開始行數(start)和限制記錄數(limit)4個引數,實現程式碼如下。

    //Rest Template使用多引數的HTTP get請求
    @GetMapping("/users/select")
    @ResponseBody
    public List<UserVo> findUsers() {
        //使用map封裝多個引數,提高可讀性
        Map<String,Object> params=new HashMap<>();
        params.put("userName","user");
        params.put("note","note");
        params.put("start",2);
        params.put("limit",8);
        //Map中的key和URI中的引數一一對應
        String url="http://localhost:8080/users/{userName}/{note}/{start}/{limit}";
        //請求後端
        ResponseEntity<List> responseEntity = restTemplate.getForEntity(url, List.class, params);
        List<UserVo> userVos=responseEntity.getBody();
        return userVos;
    }

這裡返回值是個List物件。

HTTP POST請求

新增使用者場景,因為新增使用者時欄位比較多,所以往往採用爨地請求體(Body)的方式。

    //通過POST 請求傳遞JSON 請求體(BODY)
    @GetMapping("/user/insert")
    public User insertUser(){
        UserVo userVo=new UserVo();
        userVo.setUserName("蠟筆小新");
        userVo.setSexCode(1);
        userVo.setNote("喜歡吃冰淇淋");
        String url="http://localhost:8080/user";
        //請求頭
        HttpHeaders headers=new HttpHeaders();
        //設定請求內容為JSON型別
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        //建立請求實體物件
        HttpEntity<UserVo> request=new HttpEntity<>(userVo,headers);
        User user = restTemplate.postForObject("http://localhost:8080/user", request, User.class);
        //User user=restTemplate.postForObject(url,userVo,User.class);
        System.out.println(user.getId());
        return user;
    }

HTTP DELETE請求

    //restTemplate 執行DELETE請求
    @GetMapping("/user/delete")
    public void deleteUser(){
        Long id=1L;
        restTemplate.delete("http://localhost:8080/user{id}",id);
    }

獲取響應頭和狀態碼

上面只是討論了成功獲取資源的情況,有時候請求並不能夠成功的獲取資源。例如,給出一個使用者的id,但是這個使用者在資料庫中並不存在,又如插入資料庫時發生了異常,這時報錯的資訊就可以存放在響應頭中,並且伺服器也會返回錯誤的狀態碼。在這樣的長興下獲取響應頭和HTTP狀態碼就可以辨別請求是否成功,如果是發生了錯誤,它還可以給出資訊反饋錯誤原因。

這裡假設一種情況,在插入使用者後需要它將響應頭和響應碼返回給客戶端,這時可以通過伺服器的響應頭或者響應碼判斷請求是否成功。如下程式碼

    //獲取伺服器響應頭屬性和HTTP狀態碼
    @GetMapping("/user/userEntity")
    public Map<String,Object> insertUserEntity(){
        UserVo userVo=new UserVo();
        userVo.setUserName("蠟筆小新");
        userVo.setSexCode(1);
        userVo.setNote("喜歡吃冰淇淋");
        String url="http://localhost:8080/user";
        //請求頭
        HttpHeaders headers=new HttpHeaders();
        //設定請求內容為JSON型別
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        //建立請求實體物件
        HttpEntity<UserVo> request=new HttpEntity<>(userVo,headers);
        ResponseEntity<User> responseEntity = restTemplate.postForEntity("http://localhost:8080/user2/entity", request, User.class);
        //獲取響應體
        User user=responseEntity.getBody();
        HttpHeaders respHeaders=responseEntity.getHeaders();
        //獲取響應屬性
        List<String> success=respHeaders.get("success");
        //響應的HTTP狀態碼
        int status=responseEntity.getStatusCodeValue();
        System.out.println(user.getId());
        Map<String,Object> resultMap=new HashMap<>();
        resultMap.put("body",user);
        resultMap.put("responseHeaders",respHeaders);
        resultMap.put("success",success);
        resultMap.put("status",status);
        return resultMap;
    }

這裡可以看到RestTemplate的postForEntity方法,它將返回一個ResponseEntity物件。這個物件包含了伺服器返回的響應體(Body)、狀態碼(status)和響應頭。在請求不到資源時,往往伺服器會通過這些內容給與客戶端提示。

github原始碼