@Bean
@LoadBalanced //開啟負(fù)載均衡
RestTemplate restTemplateBean() {
return new RestTemplate();
}
@Autowired
@Qualifier("restTemplateBean")
RestTemplate restTemplate;
1、GET
根據(jù)上圖可以看出GET請求方式一共提供了兩個函數(shù) getForObject嘹履、getForEntity腻扇。每個函數(shù)都有三個重載方法。下面就分別來介紹一下:
getForEntity
該方法返回的是 ResponseEntity, 該對象是 Spring對 HTTP 請求響應(yīng)的封裝砾嫉, 其中主要存儲了 HTTP 的幾個重要元素幼苛, 比如 HTTP 請求狀態(tài)碼的枚舉對象 HttpStatus (也就是我們常說的 404、 500 這些錯誤碼)焕刮、 在它的父類HttpEntity中還存儲著HTTP 請求的頭信息對象 HttpHeaders 以及泛型類型的請求體對象舶沿。
-
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
url為請求的地址, responseType為請求響應(yīng)體 body 的包裝類型配并, urlVariables為url中的參數(shù)綁定括荡。
ResponseEntity<String> entity = restTemplate.getForEntity("http://appUser/api/user/getName?name={1}", String.class, "哈哈哈哈");
其中第三個參數(shù)
哈哈哈哈會替換 url 中的{1} 占位符。 這里需要注意的是溉旋, 由于urlVariables 參數(shù)是一個可變參數(shù)畸冲,最終會將它轉(zhuǎn)換為一個Iterator, 所以它的順序會對應(yīng) url 中 占位符定義的數(shù)字順序
-
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
該方法提供的參數(shù)中观腊, 只有 urlVariables 的參數(shù)類型與上面的方法不同邑闲。 這里使用了 Map 類型, 所以使用該方法進(jìn)行參數(shù)綁定時梧油,需要在占位符中指定Map 中參數(shù)的 key 值苫耸,比如 url定義為 http://appUser/api/user/getName?name={name),在Map 類型的 urlVariables 中, 我們就需要 put 一個 key為 userName 的參數(shù)來綁定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 對象來替代之前的 url 和 urlVariables 參數(shù)來指定訪問地址和參數(shù)綁定鲸阔。 URI 是JDK java.net 包下的一個類偷霉,它表示一個統(tǒng)一資源標(biāo)識符(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
該方法可以理解為對 getForEntity 的進(jìn)一步封裝类少,
它通過 HttpMessageConverterExtractor 對 HTTP 的請求響應(yīng)體 body內(nèi)容進(jìn)行對象轉(zhuǎn)換硫狞, 實現(xiàn)請求直接返回包裝好的對象內(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增加兩個接口
@PostMapping("/addUser")
public User addUser(User user){
return user;
}
@PostMapping("/addUserJson")
public User addUserJson(@RequestBody User user){
return user;
}
兩個方法代表了不同的傳參方式漏益,一個是key/value格式绰疤,一個是json格式癣猾。
根據(jù)上圖可以看出POST請求方式一共提供了兩個函數(shù) postForEntity龙屉、postForObject、postForLocation痘儡。每個函數(shù)都有三個重載方法。下面就分別來介紹一下:
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ù)可以是一個普通對象, 也可以是一個HttpEntity對象征绎。 如果是
一個普通對象寝衫, 而非HttpEntity對象的時候, RestTemplate會將請求對象轉(zhuǎn)換為一
個HttpEntity對象來處理, 其中Object就是 request 的類型着饥, request內(nèi)容會被視
作完整的body來處理赁濒;而如果 request 是一個HttpEntity對象挪拟, 那么就會被當(dāng)作一
個完成的HTTP請求對象來處理谎柄, 這個 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)行解析粟矿。
可能有小伙伴可能會疑問了凰棉。RestTemplate中默認(rèn)提供的轉(zhuǎn)換器沒有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方法類似, 它的作用是簡化postForEntity的后續(xù)處理蒙幻。 通過直接將請求響應(yīng)的body內(nèi)容包裝成對象來返回使用映凳。requesta參數(shù)參考postForEntity的解釋說明。
示例:
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邮破,主要看第二個參數(shù)诈豌,如果第二個參數(shù)是MultiValueMap,則是以key/value形式傳遞决乎。如果第二個參數(shù)是一個普通對象队询,則是以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ù)會返回新資源的URI, 該URI就相當(dāng)于指定了返回類
型构诚,所以此方法實現(xiàn)的POST請求不需要像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ù)消費者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請求
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請求可以通過put方法調(diào)用送膳,put方法的參數(shù)和前面介紹的postForObject方法的參數(shù)基本一致员魏,只是put方法沒有返回值而已。
示例:
服務(wù)提供者appUser增加接口
@PutMapping("/put/{id}")
public User put(@PathVariable Integer id,@RequestBody User user){
System.out.println(id + "=="+user);
return user;
}
服務(wù)消費者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 對象是我要提交的參數(shù)叠聋,最后的55用來替換前面的占位符{1}
4撕阎、DELETE請求
public void delete(String url, Object... uriVariables)
public void delete(String url, Map<String, ?> uriVariables)
public void delete(URI url)
delete請求可以通過delete方法調(diào)用來實現(xiàn),如下例子:
服務(wù)提供者appUser增加接口
@DeleteMapping("/del/{id}")
public void del(@PathVariable("id") String id){
System.out.println(id);
}
服務(wù)消費者appPayr調(diào)用
@RequestMapping("/delete")
public void delete() {
restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100);
}