@Bean
@LoadBalanced //開(kāi)啟負(fù)載均衡
RestTemplate restTemplateBean() {
return new RestTemplate();
}
@Autowired
@Qualifier("restTemplateBean")
RestTemplate restTemplate;
1、GET

根據(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格式。

根據(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)容。

示例:
//調(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。


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

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);
}