iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0

一般來說很多請求的處理多半是透過前端進行,但也免不了有時候後端需要直接發送請求來處理,像是後端需要去特定 api 拿取資源又或是和其他 server 之間的溝通部分很常需要自己發送請求,Spring Boot 也有提供 RestTemplate 這個物件來輕鬆實踐,早期多半使用 Java 原生的 HttpConnectionUrl 來處理,那這次就介紹一下現在比較常用到的幾個常見 RestTemplate 方法。

這邊提供一個開放的 api 可以進行測試 (https://jsonplaceholder.typicode.com),裡面有詳細介紹有哪些路徑可以使用,可以直接用 postman 對特定位置來請求看看。下面介紹就會針對這個 api 進行請求。

getForObject()/postForObject()

只想取得回覆的 body,對於其他 header 等資訊不在意,所以 response 裡面只會單純回應對方要回傳的 body

寫一個 Class 來發送請求至 https://jsonplaceholder.typicode.com/posts/1,取得第一篇文章內容

public class RestTemplateDemo {
    static RestTemplate restTemplate = new RestTemplate();
    static String urlForGet = "https://jsonplaceholder.typicode.com/posts/1";
    static String UrlForPost = "https://jsonplaceholder.typicode.com/posts";

    public static void main(String[] args) {
        getForObject();
    }
    /**
     * getForObject
     * GET
     * response 只有回傳 api 回應內容,不帶有 header, response code...
     */
    public static String getForObject(){
        System.out.println("--- do getForObject ---");
        String response = restTemplate.getForObject(urlForGet, String.class);
        System.out.println(response);
        return response;
    }
    
    public static String postForObject(){
        System.out.println("--- do postForObject ---");
        HashMap<String, String> mapPost = new HashMap<>();
        mapPost.put("title", "新的文章標題");
        mapPost.put("body", "大家好,我是Sean!!");
        String response = restTemplate.postForObject(UrlForPost, mapPost, String.class);
        System.out.println(response);
        return response;
    }
}

執行這個方法可以在 terminal 看到回應
https://ithelp.ithome.com.tw/upload/images/20240923/20150977ntQvAh9xoW.png

https://ithelp.ithome.com.tw/upload/images/20240923/20150977kdaUZU8qON.png

getForEntity()/postForEntity()

同時需要其他資訊如 header, response code 等等,其返回值是 ResponseEntity 物件,ResponseEntity 是 Spring 對 HTTP 請求的回覆封裝,getForObject 請求內部物件方法,getForEntity 都可以使用。

使用ResponseEntity<T> responseEntity來接收回覆結果。在配合用特定方法取得封裝物件內容:

  • getBody()
  • getHeaders()
  • getStatusCode()

寫一個方法來發送請求

  	/**
     * getForEntity
     * GET
     * response 組成 ResponseEntity ,內含 body, header, response code...
     */
    public static ResponseEntity<String> getForEntity(){
        ResponseEntity<String> response = restTemplate.getForEntity(urlForGet, String.class);
        System.out.println(response);
        return response;
    }
    
     /**
     * postForEntity
     * POST
     * 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
     */
    public static ResponseEntity<String> postForEntity(){
        System.out.println("--- do postForEntity ---");
        HashMap<String, String> mapPost = new HashMap<>();
        mapPost.put("title", "新的文章標題");
        mapPost.put("body", "大家好,我是Sean!!");
        ResponseEntity<String> response = restTemplate.postForEntity(UrlForPost, mapPost, String.class);
        System.out.println(response);
        return response;
    }

main 下加入這方法且執行後可以看到回應不只有原本
https://ithelp.ithome.com.tw/upload/images/20240923/20150977AHjTcG84wq.png

https://ithelp.ithome.com.tw/upload/images/20240923/20150977W9G5wQ2fAH.png

exchange

更完整可以配置請求的相關內容,可以配置 header, HTTP method, Url 等等在送出請求之前,並且加入請求內容或是參數,最後和 get/postForEntity 一樣得到回應為封裝的 ResponseEntity。所以可以從中獲取你需要的各種資訊。

    /**
     * exchange
     * (GET) 適用任何 http method。
     * 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
     */
    public static String exchangeWithGet(){
        // 設定 header
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 建立 HttpEntity 物件,包含請求頭及請求內容(可以省略)
        HttpEntity<String> request = new HttpEntity<>("", headers);

        // 執行 GET 請求,並取得回應資料
        ResponseEntity<String> response = restTemplate.exchange(urlForGet, HttpMethod.GET, request, String.class);

        // 讀取回應內容
        String responseBody = response.getBody();
        System.out.println(responseBody);
        return responseBody;
    }

    /**
     * exchange
     * (POST) 適用任何 http method。
     * 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
     */
    public static ResponseEntity<String> exchangeWithPost(){
        System.out.println("--- do exchangeWithPost ---");

        // 設定 header
        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_JSON);

        // 建立 HttpEntity 物件,包含請求頭及請求內容(可以省略)
        Post post = new Post("新的文章標題", "大家好,我是Sean!!");
        HttpEntity<Post> request = new HttpEntity<>(post, headers);

        // 執行 GET 請求,並取得回應資料
        ResponseEntity<String> response = restTemplate.exchange(UrlForPost, HttpMethod.POST, request, String.class);

        // 讀取回應內容
        System.out.println(response);
        return response;
    }

回應部分就先省略,因為就如同上面的 getForEntity 和 postForEntity 範例一樣,

put()

    /**
     * put
     * PUT
     * 沒有回傳值
     */
    public static void put(){
        String url = "https://jsonplaceholder.typicode.com/posts/2";
        Post post = new Post("修改文章標題", "修改文章內容");
        restTemplate.put(url, post);
    }

沒有回傳

delete()

    /**
     * delete
     * DELETE
     * 沒有回傳值
     */
    public static  void delete(){
        String url = "https://jsonplaceholder.typicode.com/posts/3";
        restTemplate.delete(url);
    }

沒有回傳

完整範例

package com.oseanchen.demotest.restTemplate;

import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;

public class RestTemplateDemo {
    static RestTemplate restTemplate = new RestTemplate();
    static String urlForGet = "https://jsonplaceholder.typicode.com/posts/1";
    static String UrlForPost = "https://jsonplaceholder.typicode.com/posts";

    public static void main(String[] args) {
//        getForObject();
//        getForEntity();
//        postForObject();
        postForEntity();
//        exchangeWithGet();
//        exchangeWithPost();
//        put();
//        delete();
    }
    /**
     * getForObject
     * GET
     * response 只有回傳 api 回應內容,不帶有 header, response code...
     */
    public static String getForObject(){
        System.out.println("--- do getForObject ---");
        String response = restTemplate.getForObject(urlForGet, String.class);
        System.out.println(response);
        return response;
    }

    public static String postForObject(){
        System.out.println("--- do postForObject ---");
        HashMap<String, String> mapPost = new HashMap<>();
        mapPost.put("title", "新的文章標題");
        mapPost.put("body", "大家好,我是Sean!!");
        String response = restTemplate.postForObject(UrlForPost, mapPost, String.class);
        System.out.println(response);
        return response;
    }

    /**
     * getForEntity
     * GET
     * response 組成 ResponseEntity ,內含 body, header, response code...
     */
    public static ResponseEntity<String> getForEntity(){
        System.out.println("--- do getForEntity ---");
        ResponseEntity<String> response = restTemplate.getForEntity(urlForGet, String.class);
        System.out.println(response);
        return response;
    }

    /**
     * postForEntity
     * POST
     * 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
     */
    public static ResponseEntity<String> postForEntity(){
        System.out.println("--- do postForEntity ---");
        HashMap<String, String> mapPost = new HashMap<>();
        mapPost.put("title", "新的文章標題");
        mapPost.put("body", "大家好,我是Sean!!");
        ResponseEntity<String> response = restTemplate.postForEntity(UrlForPost, mapPost, String.class);
        System.out.println(response);
        return response;
    }

    /**
     * exchange
     * (GET) 適用任何 http method。
     * 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
     */
    public static String exchangeWithGet(){
        // 設定 header
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 建立 HttpEntity 物件,包含請求頭及請求內容(可以省略)
        HttpEntity<String> request = new HttpEntity<>("", headers);

        // 執行 GET 請求,並取得回應資料
        ResponseEntity<String> response = restTemplate.exchange(urlForGet, HttpMethod.GET, request, String.class);

        // 讀取回應內容
        String responseBody = response.getBody();
        System.out.println(responseBody);
        return responseBody;
    }

    /**
     * exchange
     * (POST) 適用任何 http method。
     * 設定 header, body 等至 HttpEntity , 回傳 response 為 ResponseEntity,內含 body, header, response code...
     */
    public static ResponseEntity<String> exchangeWithPost(){
        System.out.println("--- do exchangeWithPost ---");

        // 設定 header
        HttpHeaders headers = new HttpHeaders();

        headers.setContentType(MediaType.APPLICATION_JSON);

        // 建立 HttpEntity 物件,包含請求頭及請求內容(可以省略)
        Post post = new Post("新的文章標題", "大家好,我是Sean!!");
        HttpEntity<Post> request = new HttpEntity<>(post, headers);

        // 執行 GET 請求,並取得回應資料
        ResponseEntity<String> response = restTemplate.exchange(UrlForPost, HttpMethod.POST, request, String.class);

        // 讀取回應內容
        System.out.println(response);
        return response;
    }

    /**
     * put
     * PUT
     * 沒有回傳值
     */
    public static void put(){
        String url = "https://jsonplaceholder.typicode.com/posts/2";
        Post post = new Post("修改文章標題", "修改文章內容");
        restTemplate.put(url, post);
    }

    /**
     * delete
     * DELETE
     * 沒有回傳值
     */
    public static  void delete(){
        String url = "https://jsonplaceholder.typicode.com/posts/3";
        restTemplate.delete(url);
    }
}

總結

上述各類型的用法其實都很雷同,主要先看是否需要有進一步關於回應的各種資訊。

  • 如果不需要就可以考慮使用 get/postForObject 純粹獲取回應 body 就好。
  • 如果需要那些完整回應的資訊就可以考慮用 get/postForEntity 或 Exchange 來進行請求,這樣就可以從中獲取像是 status code, header等的資訊。
  • 如果要細部指定 header 或是各類型的方法可以使用 exchange 來進行請求可以根據需求調整,詳細可以參考下表。
  • delete, put, patch 等如果不需要回應可以直接使用。
return type set header getStatusCode() getHeaders() getBody()
getForObject/postForObject String (response body) x x x x
getForEntity/postForEntity ResponseEntity x o o o
exchange ResponseEntity o o o o
put/delete void x x x x

Ref:

相關文章也會同步更新我的部落格,有興趣也可以在裡面找其他的技術分享跟資訊。


上一篇
Day 15 - Spring AOP
下一篇
Day 17 - UnitTest (1) - 基本介紹及建立測試程式
系列文
關於我和 Spring Boot 變成家人的那件事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言