什么是 RestTemplate
RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的 REST请求方案的模板,例如 GET 请求、POST 请求、PUT 请求、DELETE 请求以及一些通用的请求执行方法 exchange 以及 execute。RestTemplate 继承自 InterceptingHttpAccessor 并且实现了 RestOperations 接口,其中 RestOptions 接口定义了基本的 RESTful 操作,这些操作在 RestTemplate 中都得到了实现。
传统情况下, java 代码里访问 RESTful 服务,一般使用 Apache 的 HTTPClient。不过此种方法使用起来太频繁。Spring 提供了一种简单便捷的模板类 RestTemplate 来进行操作。
RestTemplate的使用
一个简单的例子
@RestController
public class TestController
{
@PostMapping(value = "testPost")
public ResponseBean testPost(@RequestBody RequestBean requestBean)
{
ResponseBean responseBean = new ResponseBean();
responseBean.setRetCode("0000");
responseBean.setRetMsg("succ");
return responseBean;
}
}
使用 RestTemplate 访问该服务:
//请求地址
String url
//入参
RequestBean requestBean = new RequestBean();
requestBean.setTest1("1");
requestBean.setTest2("2");
requestBean.setTest3("3");
RestTemplate restTemplate = new RestTemplate();
ResponseBean responseBean = restTemplate.postForObject(url, requestBean, ResponseBean.class);
使用 RestTemplate 访问 RESTful 接口非常的简单粗暴无脑。(url,requestBean,ResponseBean.class)这三个参数分别代表请求地址、请求参数、HTTP响应转换成的对象类型。
RestTemplate 添加请求头 headers 和请求体 body
//headers & cookie
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.add("basecret", config.getBasecret());
headers.add("baid", config.getBaid());
List<String> cookies = new ArrayList<>();
cookies.add("COOKIE_USER" + Strings.nullToEmpty(config.getCookie()));
headers.put(HttpHeaders.COOKIE, cookies);
GET请求
如果是 get 请求,又想要把参数封装到 map 里面进行传递的话,Map 需要使用 HashMap,且 url 需要使用占位符,如下:
RestTemplate restTemplate2 = new RestTemplate();
String url
// 封装参数,这里是HashMap
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("dt", "20190225");
paramMap.put("ht", "10");
//1、使用getForObject请求接口
String result1 = template.getForObject(url, String.class, paramMap);
System.out.println("result1====================" + result1);
//2、使用exchange请求接口
HttpHeaders headers = new HttpHeaders();
headers.set("id", "lidy");
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(null,headers);
ResponseEntity<String> response2 = template.exchange(url, HttpMethod.GET, httpEntity, String.class,paramMap);
请求示例
1.GET
private static void getEmployees(){
final String uri
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);
System.out.println(result);
}
2.使用 RestTemplate 定制 HTTP 头文件
private static void getEmployees(){
final String uri
RestTemplate restTemplate = new RestTemplate();
EmployeeListVO result = restTemplate.getForObject(uri, EmployeeListVO.class);
System.out.println(result);
}
GET 请求获取相应为一个对象
private static void getEmployees(){
final String uri
RestTemplate restTemplate = new RestTemplate();
EmployeeListVO result = restTemplate.getForObject(uri, EmployeeListVO.class);
System.out.println(result);
}
URL 参数
private static void getEmployeeById(){
final String uri
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1");
RestTemplate restTemplate = new RestTemplate();
EmployeeVO result = restTemplate.getForObject(uri, EmployeeVO.class, params);
System.out.println(result);
}
POST请求
1.调用 postForObject 方法;2.调用 postForEntity 方法;3.调用 exchange 方法
postForObject 和 postForEntity 方法的区别主要在于可以在 postForEntity 方法中设置 header 的属性,当需要指定 header 的属性值的时候,使用 postForEntity 方法。exchange 方法和 postForEntity 类似,但是更灵活,exchange 还可以调用 get 请求。使用这三种方法传递参数,Map 不能定义为以下两种类型:
Map<String,Object> paramMap = new HashMap<String,Object>();
Map<String,Object> paramMap = new LinkedHashMap<String,Object>();
把 Map 类型换成 LinkedMultiValueMap 后,参数成功传递后台
MultiValueMap<String,Object> paramMap = new LinkedMultiValueMap<String,Object>();
MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
paramMap.add("dt", "20190225");
// 1、使用postForObject请求接口
String result = template.postForObject(url, paramMap, String.class);
// 2、使用postForEntity请求接口
HttpHeaders headers = new HttpHeaders();
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<MultiValueMap<String, Object>>(paramMap,headers);
ResponseEntity<String> response2 = template.postForEntity(url, httpEntity, String.class);
// 3、使用exchange请求接口
ResponseEntity<String> response3 = template.exchange(url, HttpMethod.POST, httpEntity, String.class);
如果 post 请求体是个 Json 的表单的话
//JSONObject userInfo = new JSONObject();
Map<String, Object> userInfo = Maps.newHashMap();
userInfo.put("phone", accountForm.getPhone());
userInfo.put("job", accountForm.getJob());
userInfo.put("email", accountForm.getEmail());
Map<String, Object> postBody = Maps.newHashMap();
postBody.put("userInfo", userInfo);
HttpEntity<Map> requestEntity = new HttpEntity<>(postBody, headers);
try {
ResponseEntity<String> result = restTemplate.postForEntity(config.getCreateWithAuthUrl(), requestEntity, String.class);
JsonNode jsonNode = JsonUtils.toJsonNode(result.getBody());
if (jsonNode.get("errno").asInt() == 200 || jsonNode.get("errno").asInt() == 505) {
return true;
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
private static void createEmployee(){
final String uri
EmployeeVO newEmployee = new EmployeeVO(-1, "Adam", "Gilly", "test@");
RestTemplate restTemplate = new RestTemplate();
EmployeeVO result = restTemplate.postForObject( uri, newEmployee, EmployeeVO.class);
System.out.println(result);
}
Submit Form Data
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("id", "1");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
RestTemplate restTemplate = new RestTemplate();
EmployeeVO result = restTemplate.postForObject( uri, request, EmployeeVO.class);
System.out.println(result);
PUT请求
不需要返回值的话,直接使用RestTemplate中的put方法
private static void updateEmployee(){
final String uri
Map<String, String> params = new HashMap<String, String>();
params.put("id", "2");
EmployeeVO updatedEmployee = new EmployeeVO(2, "New Name", "Gilly", "test@");
RestTemplate restTemplate = new RestTemplate();
restTemplate.put ( uri, updatedEmployee, params);
}
但是RestTemplate没有定义Put请求有参数的情况,所以Put请求需要返回结果的话,可以用exchange方法代替。
Foo updatedInstance = new Foo("newName");
updatedInstance.setId(createResponse.getBody().getId());
String resourceUrl =
fooResourceUrl + '/' + createResponse.getBody().getId();
HttpEntity<Foo> requestUpdate = new HttpEntity<>(updatedInstance, headers);
template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class);
使用.exchange的请求回调
RequestCallback requestCallback(final Foo updatedInstance) {
return clientHttpRequest -> {
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(clientHttpRequest.getBody(), updatedInstance);
clientHttpRequest.getHeaders().add(
HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
clientHttpRequest.getHeaders().add(
HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass());
};
}
DELETE请求
private static void deleteEmployee(){
final String uri
Map<String, String> params = new HashMap<String, String>();
params.put("id", "2");
RestTemplate restTemplate = new RestTemplate();
restTemplate.delete ( uri, params );
}
发送带 header 的 POST 请求
// header填充
LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.put("Content-Type", Collections.singletonList("application/json;charset=UTF-8"));
headers.put("signature", Collections.singletonList(makeSignature(form.getNewMobile())));
// body填充
JSONObject json = new JSONObject();
json.put("oldMobile", mobile);
json.put("newMobile", form.getNewMobile());
HttpEntity<String> request = new HttpEntity<String>(json.toString(), headers);
// 一个单例的restTemplate
RestTemplate restTemplate = HttpInvoker.getRestTemplate();
// 发送请求
ResponseEntity<String> response = restTemplate.postForEntity(whiteListURL, request, String.class);
String url = prometheusServer + api;
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
// 查询参数
map.add("query", sql.toString());
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/x-www-form-urlencoded");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
// 接受响应的类要与 接口响应一致,不然报错
ResponseEntity<PostResultVo> exchange = restTemplate.postForEntity(url, request, PostResultVo.class);
if (null != exchange && null != exchange.getBody() && null != exchange.getBody().getData()) {
}
发送带 header 的 GET 请求
/**
* 带header的GET请求
*/
@Test
public void getHasHeader() {
long userId = 32L;
HttpHeaders headers = new HttpHeaders();
headers.add("token", "123");
ResponseEntity<UserBean> response = restTemplate.exchange(
HttpMethod.GET,
new HttpEntity<String>(headers),
UserBean.class,
userId);
("response={}", JSON.toJSONString(response.getBody()));
}
private static void getEmployees(){
final String uri
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
System.out.println(result);
}