重新启动 provider 服务
在 consumer 中访问 hello2 接口,是 GET 请求,就调用RestTemplate 中的 getXXX() 方法 主要分为 getForObject 和 getForEntity 两大类方法,返回值不一致,getForObject 就是服务端返回的具体值,getForEntity 返回 ReponseEntity ,除了具体值,还有响应头的数据代码编写 - @GetMapping("hello4") public void hello4(){ String s = balanceRestTemplate.getForObject("http://provider/hello2?name={1}", String.class, "javaboy"); System.out.println(s); ResponseEntity<String> responseEntity = balanceRestTemplate.getForEntity("http://provider/hello2?name={1}", String.class, "javaboy"); String body = responseEntity.getBody(); System.out.println("body:" + body); HttpStatus statusCode = responseEntity.getStatusCode(); System.out.println("HttpStatus:" + statusCode); int statusCodeValue = responseEntity.getStatusCodeValue(); System.out.println("statusCodeValue:" + statusCodeValue); System.out.println("----------------header------------------"); HttpHeaders headers = responseEntity.getHeaders(); Set<Map.Entry<String, List<String>>> entries = headers.entrySet(); for (Map.Entry<String, List<String>> entry:entries) { System.out.println(entry.getKey()); System.out.println(entry.getValue()); } }代码执行结果
看清楚区别后,接下来看各自的重载方法,getForObject 和 getForEntity 分别有三个重载方法,两者的三个重载方法基本是一致的,所以,这里只看其中一种。三个重载方法,其实代表了三种传参方式。
编写代码
@GetMapping("/hello5") public void hello5() throws UnsupportedEncodingException, URISyntaxException { //多个参数的传参方式 // balanceRestTemplate.getForObject("http://provider/hello2?name={1}&age={2}", String.class, "javaboy", 32); String s = balanceRestTemplate.getForObject("http://provider/hello2?name={1}", String.class, "javaboy"); System.out.println(s); HashMap<String, Object> map = new HashMap<>(); map.put("name", "zhangsan"); s = balanceRestTemplate.getForObject("http://provider/hello2?name={name}", String.class, map); System.out.println(s); // URI 形式中文必须转码 String url = "http://provider/hello2?name=" + URLEncoder.encode("张三", "UTF-8"); s = balanceRestTemplate.getForObject(new URI(url), String.class); System.out.println(s); } 代码执行结果重启 provider 服务
接下来,我们在 consumer 中调用这两个 POST 方法 首先来看一下 POST 的所有方法: 可以看到多出来三个 postForLocation 方法,postForObject 和 postForEntity 与前面的 GET 基本一致,主要看postForObject ,看完之后再来看额外的 postForLocation在 consumer 中再定义一个方法测试 postForObject @GetMapping("/hello6") public void hello6(){ MultiValueMap map = new LinkedMultiValueMap<String,Object>(); map.add("username","javaboy"); map.add("password","123"); map.add("id",99); User user = balanceRestTemplate.postForObject("http://provider/user1", map, User.class); System.out.println(user); user.setId(98); user = balanceRestTemplate.postForObject("http://provider/user2", user, User.class); System.out.println(user); } 执行结果 额外的 postForLocation postForLocation 只对重定向的请求有左右,即响应头中有 location 返回头,返回状态码是 302 的请求 在 provider 中定义一个两个接口,其中一个是另一个的重定向结果 @Controller public class UserController { @PostMapping("/register") public String register(User user){ return "redirect:http://provider/loginPage?username=" + user.getUsername(); } @GetMapping("/loginPage") @ResponseBody public String loginPage(String username){ return "login " + username; } }在 consumer 中调用第一个接口,使用返回的 URI 调用第二个接口
@GetMapping("/hello7") public void hello7(){ MultiValueMap map = new LinkedMultiValueMap<String,Object>(); map.add("username","javaboy"); map.add("password","123"); map.add("id",99); URI uri = balanceRestTemplate.postForLocation("http://provider/register", map, User.class); System.out.println(uri); String s = balanceRestTemplate.getForObject(uri, String.class); System.out.println(s); }访问 hello7 注意在 proivder 中为 postForLocation 的接口,重定向的地址必须为绝对路径,如果是相对路径,会补上 provider 服务的 ip 和端口,但是我们使用的是 ribbon 的 restTemplate ,他会把 ip 和端口,当作服务的名字去 服务注册表中查询,导致服务失败。
postForObject 失败的例子 @Controller public class UserController { @PostMapping("/register") public String register(User user){ return "redirect:/loginPage?username=" + user.getUsername(); } @GetMapping("/loginPage") @ResponseBody public String loginPage(String username){ return "login " + username; } }单独拿出来重定向地址是可以请求成功的:
没有返回值
在 provider 中定义两个 PUT 接口,与 POST 请求类似,也是有 Key - Value 和 JSON 两种形式
@PutMapping("/user1") @ResponseBody public void updateUser1(User user){ System.out.println(user); } @PutMapping("/user2") @ResponseBody public void updateUser2(@RequestBody User user){ System.out.println(user); }然后再 consumer 服务中调用,也是 Key - Value 和 JSON 形式两种方式请求
@GetMapping("/hello8") public void hello8(){ MultiValueMap<String,Object> map = new LinkedMultiValueMap<>(); map.add("id",99); map.add("username","javaboy"); map.add("password","123"); balanceRestTemplate.put("http://provider/user1",map); User user = new User(); user.setId(100); user.setUsername("xuan"); user.setPassword("456"); balanceRestTemplate.put("http://provider/user2", user); }在 provider 服务控制台显示:
没有返回值
delete 请求也有两种方式,分别是 Key - Value 和 PathVariable 形式 首先在 provider 中定义两种类型的接口
@DeleteMapping("/user1") @ResponseBody public void deleteUser1(Integer id){ System.out.println(id); } @DeleteMapping("/user2/{id}") @ResponseBody public void deleteUser2(@PathVariable Integer id){ System.out.println(id); }在 consumer 中调用这两种请求:
@GetMapping("/hello9") public void hello9(){ balanceRestTemplate.delete("http://provider/user1?id=11"); balanceRestTemplate.delete("http://provider/user1?id={1}",22); balanceRestTemplate.delete("http://provider/user2/{1}",33); }在 provider 服务的控制台: 至此,RestTemplate 的 基本用法介绍完了