SpringBoot Web开发——使用RestTemplate发送客户端请求
文章目录
0.什么是RestTemplate?
RestTemplate是Spring框架提供的用于访问Res风格的URI请求的模板类。 可以是访问本系统内的其他微服务模块或其他系统的进行URI请求。
关于REST风格接口,可查看:SpringBoot Web开发——构建Restful风格接口
1.RestTemplate模板类源码浅析与常用方法
根据REST风格的四种请求方式:
- GET 用来访问(获取)资源
- POST 用来新建(添加)资源
- PUT 用来更新(修改)资源
- DELETE 用来删除资源
这里列出RestTemplate类部分源码:
//这里只截取方法的定义(方法名,参数,返回类型),省略底层实现细节。
//GET请求
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
public <T> T getForObject(URI url, Class<T> responseType)
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType)
//POST请求
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)
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)
//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)
//DELETE请求
public void delete(String url, Object... uriVariables)
public void delete(String url, Map<String, ?> uriVariables)
public void delete(URI url) //啥参数没有?删除所有?慎用!!!
可看到分别有以下方法:
- getForObject() / getForEntity():返回JSON对应的实体对象/返回整个ResponseEntity对象
- postForObject() / postForEntity()
- put():发送put请求无返回值
- delete():发送delete请求无返回值
上述的ResponseEntity类:继承自HttPEntity类,封装了请求后返回的响应头(包含请求内容的类型)、响应体(接口返回的JSON) 和 响应状态。
其中,上述的每种方法又有三种写法,原因是因为REST风格下请求参数有以下三种情况:
- URI单参数:对应方法参数(String url, Class responseType, Object… uriVariables)
- URI多参数:对应方法参数(String url, Class responseType, Map<String, ?> uriVariables)
- JSON参数:对应方法参数(URI url, Class responseType)
因此上述提到的方法各重载了三次,参数不一样,处理过程略有区别。
ok,接下来接具体记录一下,怎么使用RestTemplate请求后端。
2.使用RestTemplate请求后端——URI单参数(以GET/DELETE为例)
GET请求:http://localhost:8080/Word/{id}
例如: http://localhost:8080/Word/9 的请求结果:
{
"chinese":"vt.废除(法律、习惯等);取消",
"english":"abolish",
"id":9
}
复制该JSON使用GsonFormat插件自动生成以下Word实体类,或者自己手写,我这使用Lombok插件的注解,使其有GE/SET,ToString,所有参数构造,无参构造等。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Word {
private Integer id;
private String english;
private String chinese;
}
使用RestTemplate发送GET请求,结果放到word对象中:
RestTemplate restTemplate = new RestTemplate();
Integer id=9;//URI参数 Integer类型
Word word = restTemplate.getForObject("http://localhost:8080/Word/{id}", Word.class, id);
对于getForEntity()方法,返回的是整个ResponseEntity对象:
ResponseEntity<Word> responseEntity=restTemplate.getForEntity(
"http://localhost:8080/Word/{id}", Word.class, id);
responseEntity.getStatusCode();//返回HttpStatus
responseEntity.getStatusCodeValue();//返回状态值int
Word word2=responseEntity.getBody();//返回请求返回的JSON对应的对象
HttpHeaders httpHeaders=responseEntity.getHeaders();//获取请求头信息 HttpHeaders对象
httpHeaders.getContentType();//获取请求内容类型
同理:DELETE请求的URI单参数写法几乎一致:
RestTemplate restTemplate = new RestTemplate();
Integer id=9;//URI参数 Integer类型
//DELETE 无返回值
restTemplate.delete("http://localhost:8080/Word/{id}", id);
对于POST请求,本身其参数就不在URI上,将在后面的JSON参数传递中记录。
对于PUT请求,一般是传JSON参数或者URI和JSON两种参数都有。
3.使用RestTemplate请求后端——URI多参数(以GET/DELETE为例)
URI参数往往有多个,那么多个参数怎么请求呢?
这里以请求为例,postForObject的URI多参数写法 方法定义源码如下:
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)
可知参数的传递形式为Map<String, ?> uriVariables
所以,举例GET请求:http://localhost:8080/Word/{id}/{english}/{chinese}
//使用Map封装多个参数
Map<String, Object> params = new HashMap<>();
params.put("id", 89);
params.put("english", "like");
params.put("chinese", "喜欢");
String url="http://localhost:8080/Word/{id}/{english}/{chinese}";
Word word3 = restTemplate.getForObject(url, Word.class, params);
getForEntity同理,只是参数变成了 Map<String, Object> params。
RestTemplate restTemplate = new RestTemplate();
Map<String, Object> params = new HashMap<>();
params.put("id", 89);
params.put("english", "like");
//DELETE 无返回值 根据id和english删除 参数封装在params
restTemplate.delete("http://localhost:8080/Word/{id}/{english}", params);
4.使用RestTemplate请求后端——JSON参数(以POST为例)
举例接口http://localhost:8080/Word
POST请求,JSON参数格式为:
{
"id":7
"english":"abnormal",
"chinese":"a.反常的,不正常的,不规则的",
}
对应的实体类word:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Word {
private Integer id;
private String english;
private String chinese;
}
假设返回的JSON数据格式为:
{
"message":"插入单词成功!"
}
建立对应的实体类MyMessage,之后用于获取返回的信息
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MyMessage {
private String message;
}
使用RestTemplate请求后端,JSON参数,POST请求:
HttpHeaders httpHeaders = new HttpHeaders();
//设置请求头 参数类型为JSON
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
Word word = new Word(8989, "testWord", "测试单词释义");//作为参数传JSON
HttpEntity<Word> request = new HttpEntity<>(word, httpHeaders);
//URL 请求信息 返回的JSON结果映射为MyMessage类的的对象
MyMessage myMessage = restTemplate.postForObject("http://localhost:8080/Word", request, MyMessage.class);
而postForEntity()各getForEntity()一样,返回ResponseEntity对对象,数据在body中。
5.使用RestTemplate请求后端——URI参数和JSON参数都有(以PUT为例)
URI参数和JSON参数都有,PUT请求和POST请求均可,上述提过POST,这里以PUT请求为例。
举例接口http://localhost:8080/Word/{id} 按照id去更新整条word数据
PUT请求,JSON参数格式为:
{
"id":7
"english":"abnormal",
"chinese":"a.反常的,不正常的,不规则的",
}
对应的word实体类和上面一样,返回的JSON数据举例:
{
"message":"更新单词成功!"
}
对应的MyMessage实体类和上面一样。
查看RestTemplate模板类源码的PUT请求方法定义:
//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)
可看出支持三种情况且均无返回值:
- URI单参数+JSON参数
- URI多参数+JSON参数
- JSON参数
JSON参数的请求方式和POST传JSON的套路是一样的,而URI参数则和GET请求中单参数和多参数套路一样,只是将两者结合了。
使用RestTemplate请求后端,PUT请求,URI参数和JSON参数都有:
HttpHeaders httpHeaders = new HttpHeaders();
//设置请求头 参数类型为JSON
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
Word word = new Word(8989, "testWord", "测试单词释义");//作为参数传JSON
HttpEntity<Word> request = new HttpEntity<>(word, httpHeaders);
//URI单参数 同理若为多个参数:使用Map<String, Object>封装即可
Integer id=10;
restTemplate.put("http://localhost:8080/Word/{id}",request,id);
其实RestTemplate模板类中还有一些方法:patchForObject,exchange等,没来得及去摸索,暂时记录到这里。