Spring之RestTemplate使用小结
1. 基本接口
捞出源码,看一下其给出的一些常用接口,基本上可以分为下面几种
// 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()
2. Get请求
从上面的接口命名上,可以看出可以使用的有两种方式 getForObject
和 getForEntity
,那么这两种有什么区别?
- 从接口的签名上,可以看出一个是直接返回预期的对象,一个则是将对象包装到
ResponseEntity
封装类中 - 如果只关心返回结果,那么直接用
GetForObject
即可 - 如果除了返回的实体内容之外,还需要获取返回的header等信息,则可以使用
getForEntit
b. getForObject方式
首先看下完整的接口签名
复制代码@Nullable
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException ;
@Nullable
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException ;
@Nullable
public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException;
有三个重载的方法,从接口上也比较容易看出如何使用,其中有点疑惑的则是第一钟,参数应该怎么传了,下面给出上面几种的使用姿势
public class RestTestmplateTest {
private RestTemplate restTemplate;
@Before
public void init() {
restTemplate = new RestTemplate();
}
@lombok.Data
static class InnerRes {
private Status status;
private Data result;
}
@lombok.Data
static class Status {
int code;
String msg;
}
@lombok.Data
static class Data {
long id;
String theme;
String title;
String dynasty;
String explain;
String content;
String author;
}
@Test
public void testGet() {
// 使用方法一,不带参数
String url = "https://story.hhui.top/detail?id=666106231640";
InnerRes res = restTemplate.getForObject(url, InnerRes.class);
System.out.println(res);
// 使用方法一,传参替换
url = "https://story.hhui.top/detail?id={?}";
res = restTemplate.getForObject(url, InnerRes.class, "666106231640");
System.out.println(res);
// 使用方法二,map传参
url = "https://story.hhui.top/detail?id={id}";
Map<String, Object> params = new HashMap<>();
params.put("id", 666106231640L);
res = restTemplate.getForObject(url, InnerRes.class, params);
System.out.println(res);
// 使用方法三,URI访问
URI uri = URI.create("https://story.hhui.top/detail?id=666106231640");
res = restTemplate.getForObject(uri, InnerRes.class);
System.out.println(res);
}
}
看上面的testcase,后面两个方法的使用没什么好说的,主要看一下org.springframework.web.client.RestTemplate#getForObject(java.lang.String, java.lang.Class<T>, java.lang.Object...)
的使用姿势
- 根据实际传参替换url模板中的内容
- 使用方法一时,模板中使用
{?}
来代表坑位,根据实际的传参顺序来填充 - 使用方法二时,模板中使用
{xx}
, 而这个xx,对应的就是map中的key
c. getForEntity方式
既然getForObject有三种使用方法,那么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;
3. Post请求
从上面的接口说明上看,post请求除了有forObject 和 forEntity之外,还多了个forLocation;其次post与get一个明显的区别就是传参的姿势问题,get的参数一般会待在url上;post的则更常见的是通过表单的方式提交
因此接下来关注的重点在于forLocation是什么,以及如何传参
a. 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 ;
上面的三个方法,看起来和前面并没有太大的区别,只是多了一个request参数,那么具体的使用如何呢?
@Test
public void testPost() {
String url = "http://localhost:8080/post";
String email = "[email protected]";
String nick = "一灰灰Blog";
// 表单参数
MultiValueMap<String, String> request = new LinkedMultiValueMap<>();
request.add("email", email);
request.add("nick", nick);
// 使用方法三
URI uri = URI.create(url);
String ans = restTemplate.postForObject(uri, request, String.class);
System.out.println(ans);
// 使用方法一
ans = restTemplate.postForObject(url, request, String.class);
System.out.println(ans);
// 使用方法一,但是结合表单参数和uri参数的方式,其中uri参数的填充和get请求一致
request.clear();
request.add("email", email);
ans = restTemplate.postForObject(url + "?nick={?}", request, String.class, nick);
System.out.println(ans);
// 使用方法二
Map<String, String> params = new HashMap<>();
params.put("nick", nick);
ans = restTemplate.postForObject(url + "?nick={nick}", request, String.class, params);
System.out.println(ans);
}
b. 传递Json
/**
* post请求json数据(添加请求头)并传递表单参数
*/
public static void test2(){
RestTemplate restTemplate = new RestTemplate();
// 表单参数
Map<String, String> params = new HashMap<String, String>();
params.put("id", "123");
//创建请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
String url = "http://localhost:8087/callBackFor?id={id}";
// Json参数
User student = new User("sansan",10);
HttpEntity<User> entity = new HttpEntity<User>(student, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, entity, String.class, params);
String user = responseEntity.getBody();//{"msg":"调用成功!","code":1}
System.out.println(user);
}
c. postForEntity
和前面的使用姿势一样,无非是多了一层包装而已,略过不讲
标签:String,url,Spring,RestTemplate,request,class,restTemplate,小结,public From: https://www.cnblogs.com/firsthelloworld/p/17932315.html