spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。
在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。
RestTemplate类的设计原则与许多其他Spring *模板类(例如JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
RestTemplate默认依赖JDK提供http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。
RestTemplate类中定义了大约四十个与 REST 资源交互的方法,其中大多数都对应于HTTP的方法。但是仔细分析,里面只有十二种方法。其余都是这12种方法的重载形式。下表描述了RestTemplate的12个独立方法。
序号 | 方法 | 重载方法数 | 描述 |
---|---|---|---|
1 | delete() | 3 | 在特定的 URL 上对资源执行 HTTP DELETE 操作 |
2 | exchange() | 8 | 在 URL上执行特定的 HTTP 方法,返回包含对象的 ResponseEntity,这个对象是在响应体中映射得到的 |
3 | excute() | 3 | 在 URL上执行特定的 HTTP 方法,返回从响应体中映射得到的对象 |
4 | getForObject() | 3 | 发送一个 HTTP GET请求,返回的 请求体将映射成一个对象 |
5 | getForEntity() | 3 | 发送一个 HTTP GET请求,返回的 ResponseEntity包含了响应体所映射成的对象 |
6 | HeadForHeaders() | 3 | 发送一个 HTTP HEAD请求,返回包含特定资源URL的HTTP头 |
7 | optionsForAllow() | 3 | 发送一个 HTTP OPTIONS请求,返回对特定URL的Allow头信息 |
8 | postForObject() | 3 | POST数据到一个URL,返回根据响应体匹配形成的对象 |
9 | postForEntity() | 3 | POST数据到一个URL,返回包含一个对象的ResponseEntiry,这个对象是从响应体中映射得到的 |
10 | postForLocation() | 3 | POST数据到一个URL,返回新创建资源的URL |
11 | put() | 3 | PUT资源到一个URL |
12 | patchForObject() | 3 | PATCH数据到一个URL,返回根据响应体匹配形成的对象 |
简单分析源码可以看出以下几个特点
除了TRACE意外,RestTemplate涵盖了所有的HTTP动作。除此之外,exchange()和excute()提供了较低层次的通用方法来使用任意的HTP方法,特定的方法其实最后都是走的excete()
方法;
大多数操作都是以三种方式进行了重载:
org.springframework.web.client
包下源码接口:
<T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> T getForObject(URI url, Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
throws RestClientException;
<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException;
<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;
简单查询,uri里不带参数
public static void testGet1() {
final String uri = "http://localhost:8080/students";
RestTemplate restTemplate = new RestTemplate();
String object = restTemplate.getForObject(uri, String.class);
System.out.println(object);
}
url参数
public static void testGet2() {
String uri = "http://localost:8080/student/{studentId}";
RestTemplate restTemplate = new RestTemplate();
int studentId = 1;
Student student = restTemplate.getForObject(uri, Student.class, studentId);
System.out.println(student);
}
public static void testGet3() {
String uri = "http://localost:8080/student/{studentId}";
RestTemplate restTemplate = new RestTemplate();
int studentId = 1;
Map<String, Integer> params = new HashMap<String, Integer>();
params.put("studentId", studentId);
Student student = restTemplate.getForObject(uri, Student.class, params);
System.out.println(student);
}
如果GET方法请求参数需要添加认证、Header头信息等,则需要使用exchange()方法,见下文。
上文中提到,xxForObject()方法与xxForEntity()方法的区别是后者可以同时返回对象和响应头、状态码。能在响应中读取到这头信息是很有用的。但是如果想在发送给服务器的请求中设置头信息的话,怎么办呢?这就是RestTemplate的exchange()的用武之地。
exchange()的 8 个接口 源码:
<T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
Class<T> responseType, Object... uriVariables) throws RestClientException;
<T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> ResponseEntity<T> exchange(URI url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
Class<T> responseType) throws RestClientException;
<T> ResponseEntity<T> exchange(String url,HttpMethod method, @Nullable HttpEntity<?> requestEntity,
ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RestClientException;
<T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
ParameterizedTypeReference<T> responseType, Map<String, ?> uriVariables) throws RestClientException;
<T> ResponseEntity<T> exchange(URI url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
ParameterizedTypeReference<T> responseType) throws RestClientException;
<T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType)
throws RestClientException;
<T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
throws RestClientException;
exchange()方法使用HttpMethod参数来表明要使用的HTTP动作。根据此参数,该方法可以与上文具体的HTTP方法一样的工作。
public void testGet4() {
HttpHeaders headers = new HttpHeaders();
headers.set("kbn-xsrf", "true");
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
// 手动添加认证
String userName = "root";
String password = "123456";
String str = userName + ":" + password;
String auth = "Basic " + Base64GeneratorUtil.str2Base64(str);
headers.set("Authorization", auth);
// 如果需要 还可以在这里添加一些json字符串信息
String jsonObj = "{}";
HttpEntity<String> request = new HttpEntity<>(jsonObj, headers);
String uri = "http://localost:8080/student/{studentId}";
RestTemplate restTemplate = new RestTemplate();
int studentId = 1;
ResponseEntity<Student> entity = restTemplate.exchange(uri, HttpMethod.PUT, request, Student.class, studentId);
Student student = entity.getBody();
HttpStatus statusCode = entity.getStatusCode();
HttpHeaders headers1 = entity.getHeaders();
}
略。
原文:https://www.cnblogs.com/kjgym/p/11767337.html