SpringCloud學(xué)習(xí)(五)之RestTemplate幾種請(qǐng)求方式的使用

    @Bean
    @LoadBalanced    //開(kāi)啟負(fù)載均衡
    RestTemplate restTemplateBean() {
        return new RestTemplate();
    }

    @Autowired
    @Qualifier("restTemplateBean")
    RestTemplate restTemplate;

1、GET

image.png

根據(jù)上圖可以看出GET請(qǐng)求方式一共提供了兩個(gè)函數(shù) getForObject、getForEntity。每個(gè)函數(shù)都有三個(gè)重載方法。下面就分別來(lái)介紹一下:

getForEntity

該方法返回的是 ResponseEntity, 該對(duì)象是 Spring對(duì) HTTP 請(qǐng)求響應(yīng)的封裝, 其中主要存儲(chǔ)了 HTTP 的幾個(gè)重要元素, 比如 HTTP 請(qǐng)求狀態(tài)碼的枚舉對(duì)象 HttpStatus (也就是我們常說(shuō)的 404、 500 這些錯(cuò)誤碼)、 在它的父類HttpEntity中還存儲(chǔ)著HTTP 請(qǐng)求的頭信息對(duì)象 HttpHeaders 以及泛型類型的請(qǐng)求體對(duì)象。

  • public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
    url為請(qǐng)求的地址, responseType為請(qǐng)求響應(yīng)體 body 的包裝類型, urlVariables為url中的參數(shù)綁定。
ResponseEntity<String> entity = restTemplate.getForEntity("http://appUser/api/user/getName?name={1}", String.class, "哈哈哈哈");

其中第三個(gè)參數(shù)哈哈哈哈會(huì)替換 url 中的{1} 占位符。 這里需要注意的是, 由于urlVariables 參數(shù)是一個(gè)可變參數(shù),最終會(huì)將它轉(zhuǎn)換為一個(gè)Iterator, 所以它的順序會(huì)對(duì)應(yīng) url 中 占位符定義的數(shù)字順序

  • public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
    該方法提供的參數(shù)中, 只有 urlVariables 的參數(shù)類型與上面的方法不同。 這里使用了 Map 類型, 所以使用該方法進(jìn)行參數(shù)綁定時(shí),需要在占位符中指定Map 中參數(shù)的 key 值,比如 url定義為 http://appUser/api/user/getName?name={name),在Map 類型的 urlVariables 中, 我們就需要 put 一個(gè) key為 userName 的參數(shù)來(lái)綁定url 中 {name} 占位符的值, 比如:
HashMap<String , String > map = new HashMap<>();
map.put("name","嘿哈嘿哈");
entity = restTemplate.getForEntity("http://appUser/api/user/getName?name={1}", String.class,map);
  • public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
    該方法使用URI 對(duì)象來(lái)替代之前的 url 和 urlVariables 參數(shù)來(lái)指定訪問(wèn)地址和參數(shù)綁定。 URI 是JDK java.net 包下的一個(gè)類,它表示一個(gè)統(tǒng)一資源標(biāo)識(shí)符(Uniform Resource Identifier)引用。
//如果是中文記得轉(zhuǎn)碼
        String url = "http://appUser/api/user/getName?name=" + URLEncoder.encode("紅紅火火恍恍惚惚","UTF-8");
        URI uri = URI.create(url);
        entity =  restTemplate.getForEntity(uri,String.class);

getForObject

該方法可以理解為對(duì) getForEntity 的進(jìn)一步封裝,
它通過(guò) HttpMessageConverterExtractor 對(duì) HTTP 的請(qǐng)求響應(yīng)體 body內(nèi)容進(jìn)行對(duì)象轉(zhuǎn)換, 實(shí)現(xiàn)請(qǐng)求直接返回包裝好的對(duì)象內(nèi)容

  • public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
  String rest = restTemplate.getForObject("http://appUser/api/user/getName?name={1}", String.class,name);
  • public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
        HashMap<String, Object> map = new HashMap<String,Object>();
        map.put("name",name);
        rest = restTemplate.getForObject("http://appUser/api/user/getName?name={name}", String.class,map);
  • public <T> T getForObject(URI url, Class<T> responseType)
        //如果是中文記得轉(zhuǎn)碼
        String url = "http://appUser/api/user/getName?name=" + URLEncoder.encode(name,"UTF-8");
        URI uri = URI.create(url);
        rest = restTemplate.getForObject(uri,String.class);

2、POST

服務(wù)提供者appUser增加兩個(gè)接口

    @PostMapping("/addUser")
    public User addUser(User user){
        return user;
    }

    @PostMapping("/addUserJson")
    public User addUserJson(@RequestBody User user){
        return user;
    }

兩個(gè)方法代表了不同的傳參方式,一個(gè)是key/value格式,一個(gè)是json格式。


image.png

根據(jù)上圖可以看出POST請(qǐng)求方式一共提供了兩個(gè)函數(shù) postForEntity、postForObject、postForLocation。每個(gè)函數(shù)都有三個(gè)重載方法。下面就分別來(lái)介紹一下:

postForEntity

  • public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
  • public <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
  • public <T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType)

這些函數(shù)中的參數(shù)用法大部分與getForEntity一致。 這里需要注意的是新增加的
request參數(shù), 該參數(shù)可以是一個(gè)普通對(duì)象, 也可以是一個(gè)HttpEntity對(duì)象。 如果是
一個(gè)普通對(duì)象, 而非HttpEntity對(duì)象的時(shí)候, RestTemplate會(huì)將請(qǐng)求對(duì)象轉(zhuǎn)換為一
個(gè)HttpEntity對(duì)象來(lái)處理, 其中Object就是 request 的類型, request內(nèi)容會(huì)被視
作完整的body來(lái)處理;而如果 request 是一個(gè)HttpEntity對(duì)象, 那么就會(huì)被當(dāng)作一
個(gè)完成的HTTP請(qǐng)求對(duì)象來(lái)處理, 這個(gè) request 中不僅包含了body的內(nèi)容, 也包含了
header的內(nèi)容。


image.png

示例:

//調(diào)用addUser方法
 MultiValueMap map = new LinkedMultiValueMap();
 map.add("id","1");
 map.add("name","gongj");
 ResponseEntity<User> userResponseEntity = restTemplate.postForEntity("http://appUser/api/user/addUser", map, User.class);

//調(diào)用addUserJson方法
User user = new User();
user.setId("87777");
user.setName("哈哈哈哈哈");
userResponseEntity = restTemplate.postForEntity("http://appUser/api/user/addUserJson", user, User.class);

注:需要使用 LinkedMultiValueMap ,不能使用HashMap。使用FormHttpMessageConverter進(jìn)行解析。
可能有小伙伴可能會(huì)疑問(wèn)了。RestTemplate中默認(rèn)提供的轉(zhuǎn)換器沒(méi)有FormHttpMessageConverter???但是默認(rèn)提供的AllEncompassingFormHttpMessageConverter繼承了FormHttpMessageConverter。

image.png

image.png

傳遞類型為HashMap,可以發(fā)現(xiàn)被解析成了json字符串。用的是MappingJackson2HttpMessageConverter進(jìn)行解析。


image.png

postForObject

  • public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
  • public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
  • public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType)
    該方法跟getForObject方法類似, 它的作用是簡(jiǎn)化postForEntity的后續(xù)處理。 通過(guò)直接將請(qǐng)求響應(yīng)的body內(nèi)容包裝成對(duì)象來(lái)返回使用。requesta參數(shù)參考postForEntity的解釋說(shuō)明。

示例:

MultiValueMap map = new LinkedMultiValueMap();
map.add("id","1");
map.add("name","gongj");
User user = restTemplate.postForObject("http://appUser/api/user/addUser", map, User.class);

user.setId("99");
user.setName("高興哈哈哈");
user = restTemplate.postForObject("http://appUser/api/user/addUserJson", user, User.class);

POST參數(shù)到底是key/value還是json,主要看第二個(gè)參數(shù),如果第二個(gè)參數(shù)是MultiValueMap,則是以key/value形式傳遞。如果第二個(gè)參數(shù)是一個(gè)普通對(duì)象,則是以json形式傳遞。

postForLocation

  • public URI postForLocation(String url, @Nullable Object request, Object... uriVariables)
  • public URI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables)
  • public URI postForLocation(URI url, @Nullable Object request)

由于 postForLocation 函數(shù)會(huì)返回新資源的URI, 該URI就相當(dāng)于指定了返回類
型,所以此方法實(shí)現(xiàn)的POST請(qǐng)求不需要像postForEntity和postForObject那樣指
定responseType。 其他的參數(shù)用法相同。

服務(wù)提供者appUser增加方法

@PostMapping("/register")
    public String register(User user){
        return "redirect:http://appUser/loginPage?name=" + user.getName();
    }

    @GetMapping("/loginPage")
    @ResponseBody
    public String loginPage(String name){
        return "loginPage:" + name;
    }

服務(wù)消費(fèi)者appPay

  @GetMapping("/register")
    public void register(){
        MultiValueMap map = new LinkedMultiValueMap();
        map.add("id","1");
        map.add("name","gongj"); 
//調(diào)用register
        URI uri = restTemplate.postForLocation("http://appUser/register", map);
        System.out.println(uri);
//調(diào)用uri 
        String s = restTemplate.getForObject(uri, String.class);
        System.out.println(s);
    }

3、PUT請(qǐng)求

  • public void put(String url, @Nullable Object request, Object... uriVariables)
  • public void put(String url, @Nullable Object request, Map<String, ?> uriVariables)
  • public void put(URI url, @Nullable Object request)

PUT請(qǐng)求可以通過(guò)put方法調(diào)用,put方法的參數(shù)和前面介紹的postForObject方法的參數(shù)基本一致,只是put方法沒(méi)有返回值而已。
示例:
服務(wù)提供者appUser增加接口

@PutMapping("/put/{id}")
    public User put(@PathVariable Integer id,@RequestBody User user){
        System.out.println(id + "=="+user);
        return user;
    }

服務(wù)消費(fèi)者appPayr調(diào)用

 @RequestMapping("/put")
    public void put() {
        User user = new User();
        user.setId("99");
        user.setName("高興哈哈哈");
        restTemplate.put("http://appUser/api/user/put/{1}", user,55);
    }

user 對(duì)象是我要提交的參數(shù),最后的55用來(lái)替換前面的占位符{1}

4、DELETE請(qǐng)求

  • public void delete(String url, Object... uriVariables)
  • public void delete(String url, Map<String, ?> uriVariables)
  • public void delete(URI url)

delete請(qǐng)求可以通過(guò)delete方法調(diào)用來(lái)實(shí)現(xiàn),如下例子:

服務(wù)提供者appUser增加接口

@DeleteMapping("/del/{id}")
    public void del(@PathVariable("id") String id){
        System.out.println(id);
    }

服務(wù)消費(fèi)者appPayr調(diào)用

@RequestMapping("/delete")
public void delete() {
    restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100);
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容