使用 RestTemplate 消费 REST 端点
Spring应用可以采用多种方式来消费REST API,包括以下几种方式:
- RestTemplate:Spring核心框架提供的简单、同步REST客户端。
- Traverson:Spring HATEOAS提供的支持超链接、同步的REST客户端,其灵感来源于同名的JavaScript库。
- WebClient:Spring 5所引入的反应式、异步REST客户端。
从客户端的角度来看,与REST资源进行交互涉及很多工作,而且大多数都是很单调乏味的样板式代码。如果使用较低层级HTTP库,客户端就需要创建一个客户端实例和请求对象、执行请求、解析响应、将响应映射为领域对象,并且还要处理这个过程中可能会抛出的所有异常。不管发送什么样的HTTP请求,这种样板代码都要不断重复。
为了避免这种样板代码,Spring提供了RestTemplate。就像JDBCTemplate能够处理JDBC中丑陋的那部分代码一样,RestTemplate也能够将你从消费REST资源所面临的单调工作中解放出来。
RestTemplate对每种标准的HTTP方法都提供了至少一个方法。
execute()和exchange()提供了较低层次的通用方法,以便于进行任意的HTTP操作。
表中的大多数操作都以3种方法的形式进行了重载。
- 使用String作为URL格式,并使用可变参数列表指明URL参数。
- 使用String作为URL格式,并使用Map<String,String>指明URL参数。
- 使用java.net.URI作为URL格式,不支持参数化URL。
要使用RestTemplate,你可以在需要的地方创建一个实例:
RestTemplate rest = new RestTemplate();
也可以将其声明为一个bean并注入到需要的地方:
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
GET请求
//样例一:不带参数
JSONArray jsonArray = this.restTemplate.getForObject("http://localhost:8080/user/getUserList", JSONArray.class);
log.info("{}", jsonArray);
//样例二:通过可变参数携带多个值
SysUser sysUser = this.restTemplate.getForObject("http://localhost:8080/user/getUserByAccount?account={account}", SysUser.class, "10001");
log.info("{}", JSON.toJSONString(sysUser));
//样例三:通过map携带参数
Map<String,String> map = new HashMap<>();
map.put("account","10001");
SysUser sysUser = this.restTemplate.getForObject("http://localhost:8080/user/getUserByAccount?account={account}", SysUser.class, map);
log.info("{}", JSON.toJSONString(sysUser));
//样例四:使用URI
URI uri = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/user/getUserByAccount?account={account}").build("10001");
SysUser sysUser = this.restTemplate.getForObject(uri,SysUser.class);
log.info("{}", JSON.toJSONString(sysUser));
Map<String,String> urlParamMap = new HashMap<>();
urlParamMap.put("account","10001");
ResponseEntity<SysUser> forEntity = this.restTemplate.getForEntity("http://localhost:8080/user/getUserByAccount?account={account}", SysUser.class, urlParamMap);
SysUser body = forEntity.getBody();
log.info("{}", JSON.toJSONString(body));
POST请求
SysRole sysRole = new SysRole();
sysRole.setRoleCode("common_user");
sysRole.setRoleName("普通用户");
JSONObject jsonObject = this.restTemplate.postForObject("http://localhost:8080/role/saveRole", sysRole, JSONObject.class);
log.info("{}", jsonObject);
SysRole sysRole = new SysRole();
sysRole.setRoleCode("common_admin");
sysRole.setRoleName("普通管理员");
ResponseEntity<JSONObject> postForEntity = this.restTemplate.postForEntity("http://localhost:8080/role/saveRole", sysRole, JSONObject.class);
JSONObject body = postForEntity.getBody();
log.info("{}", body);
SysRole sysRole = new SysRole();
sysRole.setRoleCode("common_admin");
sysRole.setRoleName("普通管理员");
URI uri = this.restTemplate.postForLocation("http://localhost:8080/role/saveRole", sysRole);
log.info("{}", uri);
使用exchange发起请求
Map<String,String> map = new HashMap<>();
map.put("account","10001");
ResponseEntity<SysUser> exchange = this.restTemplate.exchange("http://localhost:8080/user/getUserByAccount?account={account}", HttpMethod.GET, null, SysUser.class, map);
SysUser body = exchange.getBody();
log.info("{}", body);