不积跬步,无以至千里;不积小流,无以成江海。
Spring学习
RestTemplate
spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,只需要传入url,入参以及返回值类型即可。
相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。
基本接口
// get 请求 public <T> T getForObject(); public <T> ResponseEntity<T> getForEntity(); // head 请求 public HttpHeaders headForHeaders(); // post 请求 public URI postForLocation(); public <T> T postForObject(); public <T> ResponseEntity<T> postForEntity(); // put 请求 public void put(); // pathch public <T> T patchForObject // delete public void delete() // options public Set<HttpMethod> optionsForAllow // exchange public <T> ResponseEntity<T> exchange()
- GET请求
在RestTemplate中,发送一个GET请求,可以通过如下两种方式:
第一种:getForEntity:
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException ; public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException; public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;
getForEntity方法的返回值是一个ResponseEntity<T>
,是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。
例子(没有参数):
@RequestMapping("/gethello") public String getHello() { ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/hello", String.class); String body = responseEntity.getBody(); return body; }
解释:
getForEntity的第一个参数是要调用的服务的地址,这里调用了服务提供者提供的/hello接口,注意这里是通过服务名调用而不是服务地址,如果写成服务地址就没法实现客户端负载均衡了;
getForEntity第二个参数String.class表示我希望返回的body类型是String
结果:
hello
例子(有参数)
@RequestMapping("/sayhello") public String sayHello() { ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={1}", String.class, "张三"); return responseEntity.getBody(); }
@RequestMapping("/sayhello2") public String sayHello2() { Map<String, String> map = new HashMap<>(); map.put("name", "李四"); ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://HELLO-SERVICE/sayhello?name={name}", String.class, map); return responseEntity.getBody(); }
解释:
用一个数字做占位符,最后是一个可变长度的参数,来一一替换前面的占位符
使用name={name}这种形式,最后一个参数是一个map,map的key即为前边占位符的名字,map的value为参数值
第二种:getForObject
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException ; public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException ; public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException;
getForObject函数实际上是对getForEntity函数的进一步封装,只关注返回的消息体的内容,对其他信息都不关注
例子:
@RequestMapping("/book2") public Book book2() { Book book = restTemplate.getForObject("http://HELLO-SERVICE/getbook1", Book.class); return book; }
-
POST请求
在RestTemplate中,POST请求可以通过如下三个方法来发起:
第一种:postForObject
public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException ; public <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException; public <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException ;
例子:
@RequestMapping("/book3") public Book book3() { Book book = restTemplate.postForObject("http://HELLO-SERVICE/getbook2", book, Book.class); return book; }
方法的第一参数表示要调用的服务的地址,第二个参数表示上传的参数,第三个参数表示返回的消息体的数据类型
第二种:postForEntity
和前面的使用姿势一样,无非是多了一层包装而已,略过不讲
第三种:postForLocation
postForLocation也是提交新资源,提交成功之后,返回新资源的URI,postForLocation的参数和前面两种的参数基本一致,只不过该方法的返回值为Uri,这个只需要服务提供者返回一个Uri即可,该Uri表示新资源的位置。