@Bean
@LoadBalanced //开启负载均衡
RestTemplate restTemplateBean() {
return new RestTemplate();
}
@Autowired
@Qualifier("restTemplateBean")
RestTemplate restTemplate;
1、GET
image.png根据上图可以看出GET请求方式一共提供了两个函数 getForObject、getForEntity。每个函数都有三个重载方法。下面就分别来介绍一下:
getForEntity
该方法返回的是 ResponseEntity, 该对象是 Spring对 HTTP 请求响应的封装, 其中主要存储了 HTTP 的几个重要元素, 比如 HTTP 请求状态码的枚举对象 HttpStatus (也就是我们常说的 404、 500 这些错误码)、 在它的父类HttpEntity中还存储着HTTP 请求的头信息对象 HttpHeaders 以及泛型类型的请求体对象。
-
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
url为请求的地址, responseType为请求响应体 body 的包装类型, urlVariables为url中的参数绑定。
ResponseEntity<String> entity = restTemplate.getForEntity("http://appUser/api/user/getName?name={1}", String.class, "哈哈哈哈");
其中第三个参数
哈哈哈哈会替换 url 中的{1} 占位符。 这里需要注意的是, 由于urlVariables 参数是一个可变参数,最终会将它转换为一个Iterator, 所以它的顺序会对应 url 中 占位符定义的数字顺序
-
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
该方法提供的参数中, 只有 urlVariables 的参数类型与上面的方法不同。 这里使用了 Map 类型, 所以使用该方法进行参数绑定时,需要在占位符中指定Map 中参数的 key 值,比如 url定义为 http://appUser/api/user/getName?name={name),在Map 类型的 urlVariables 中, 我们就需要 put 一个 key为 userName 的参数来绑定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 参数来指定访问地址和参数绑定。 URI 是JDK java.net 包下的一个类,它表示一个统一资源标识符(Uniform Resource Identifier)引用。
//如果是中文记得转码
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 的进一步封装,
它通过 HttpMessageConverterExtractor 对 HTTP 的请求响应体 body内容进行对象转换, 实现请求直接返回包装好的对象内容
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)
//如果是中文记得转码
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
服务提供者appUser增加两个接口
@PostMapping("/addUser")
public User addUser(User user){
return user;
}
@PostMapping("/addUserJson")
public User addUserJson(@RequestBody User user){
return user;
}
两个方法代表了不同的传参方式,一个是key/value格式,一个是json格式。
image.png
根据上图可以看出POST请求方式一共提供了两个函数 postForEntity、postForObject、postForLocation。每个函数都有三个重载方法。下面就分别来介绍一下:
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)
这些函数中的参数用法大部分与getForEntity一致。 这里需要注意的是新增加的
request参数, 该参数可以是一个普通对象, 也可以是一个HttpEntity对象。 如果是
一个普通对象, 而非HttpEntity对象的时候, RestTemplate会将请求对象转换为一
个HttpEntity对象来处理, 其中Object就是 request 的类型, request内容会被视
作完整的body来处理;而如果 request 是一个HttpEntity对象, 那么就会被当作一
个完成的HTTP请求对象来处理, 这个 request 中不仅包含了body的内容, 也包含了
header的内容。
image.png
示例:
//调用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);
//调用addUserJson方法
User user = new User();
user.setId("87777");
user.setName("哈哈哈哈哈");
userResponseEntity = restTemplate.postForEntity("http://appUser/api/user/addUserJson", user, User.class);
注:需要使用 LinkedMultiValueMap ,不能使用HashMap。
使用FormHttpMessageConverter进行解析。
可能有小伙伴可能会疑问了。RestTemplate中默认提供的转换器没有FormHttpMessageConverter啊?但是默认提供的AllEncompassingFormHttpMessageConverter继承了FormHttpMessageConverter。
image.png
传递类型为HashMap,可以发现被解析成了json字符串。用的是MappingJackson2HttpMessageConverter进行解析。
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方法类似, 它的作用是简化postForEntity的后续处理。 通过直接将请求响应的body内容包装成对象来返回使用。requesta参数参考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参数到底是key/value还是json,主要看第二个参数,如果第二个参数是MultiValueMap,则是以key/value形式传递。如果第二个参数是一个普通对象,则是以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 函数会返回新资源的URI, 该URI就相当于指定了返回类
型,所以此方法实现的POST请求不需要像postForEntity和postForObject那样指
定responseType。 其他的参数用法相同。
服务提供者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;
}
服务消费者appPay
@GetMapping("/register")
public void register(){
MultiValueMap map = new LinkedMultiValueMap();
map.add("id","1");
map.add("name","gongj");
//调用register
URI uri = restTemplate.postForLocation("http://appUser/register", map);
System.out.println(uri);
//调用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方法调用,put方法的参数和前面介绍的postForObject方法的参数基本一致,只是put方法没有返回值而已。
示例:
服务提供者appUser增加接口
@PutMapping("/put/{id}")
public User put(@PathVariable Integer id,@RequestBody User user){
System.out.println(id + "=="+user);
return user;
}
服务消费者appPayr调用
@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 对象是我要提交的参数,最后的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方法调用来实现,如下例子:
服务提供者appUser增加接口
@DeleteMapping("/del/{id}")
public void del(@PathVariable("id") String id){
System.out.println(id);
}
服务消费者appPayr调用
@RequestMapping("/delete")
public void delete() {
restTemplate.delete("http://HELLO-SERVICE/getbook4/{1}", 100);
}
网友评论