spring resttemplate文档阅读

This commit is contained in:
2023-04-21 17:40:17 +08:00
parent e5b607eb9d
commit c78febc0d7

View File

@@ -0,0 +1,111 @@
# RestTemplate
RestTemplate提供了比http client library更高层级的api其允许以更加容易的方式来调用rest接口。
## 初始化
RestTemplate的默认构造函数使用`java.net.HttpURLConnection`来执行http请求。
## URIs
RestTemplate的许多方法都接收一个URI template和URI tempalte变量要么作为`String`变量参数,要么作为`Map<String,String>`.
如下示例使用了String类型参数
```java
String result = restTemplate.getForObject(
"https://example.com/hotels/{hotel}/bookings/{booking}", String.class, "42", "21");
```
如下示例则是使用了Map类型的参数
```java
Map<String, String> vars = Collections.singletonMap("hotel", "42");
String result = restTemplate.getForObject(
"https://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);
```
URI tempalte是自动编码的按如下示例所示
```java
restTemplate.getForObject("https://example.com/hotel list", String.class);
// Results in request to "https://example.com/hotel%20list"
```
## headers
可以通过`exchange()`方法来指定请求的headers如下所示
```java
String uriTemplate = "https://example.com/hotels/{hotel}";
URI uri = UriComponentsBuilder.fromUriString(uriTemplate).build(42);
RequestEntity<Void> requestEntity = RequestEntity.get(uri)
.header("MyRequestHeader", "MyValue")
.build();
ResponseEntity<String> response = template.exchange(requestEntity, String.class);
String responseHeader = response.getHeaders().getFirst("MyResponseHeader");
String body = response.getBody();
```
## body
向RestTemplate中方法传入的参数或RestTemplate方法返回的对象其与raw content之间的转换都是通过`HttpMessageConverter`来执行的。
在一个POST请求中传入到RestTemplate方法中的参数会被序列化到请求的body中
```java
URI location = template.postForLocation("https://example.com/people", person);
```
**使用者并不需要显式设置请求体的`Content-Type`header**。在大多数情况下都可以基于source Object类型找到一个合适的message converter而被选中的message converter则会设置content type header。如果在必要情况下可以通过`exchange`方法来显式提供`Content-Type` header并且在设置content type请求头之后会影响选中的message converter。
如下示例显示了一个get请求将响应的body反序列化为方法的返回类型
```java
Person person = restTemplate.getForObject("https://example.com/people/{id}", Person.class, 42);
```
类似于`Content-Type`请求头,`Accept`请求头也不需要显式设置。在多数情况下根据方法返回类型选中的message converter会帮助注入Accept请求头。在必要情况下可以通过`exchange()`方法来指定要传递的`Accept`请求头。
默认情况下RestTemplate注册了所有内置的message converter。
## Multipart
如果需要发送multipart数据需要提供一个`MultiValueMap<String,Object>`该map的value可以是一个part content objectfile part resource含有part content和header的HttpEntity。
```java
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("fieldPart", "fieldValue");
parts.add("filePart", new FileSystemResource("...logo.png"));
parts.add("jsonPart", new Person("Jason"));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
parts.add("xmlPart", new HttpEntity<>(myBean, headers));
```
当MultiValueMap构建好之后可以将其传递给RestTemplate如下所示
```java
MultiValueMap<String, Object> parts = ...;
template.postForObject("https://example.com/upload", parts, Void.class);
```
如果MultiValueMap至少含有一个不为String的值那么Content-Type将会被`FormHttpMessageConverter`设置为`multipart/form-data`
如果MultiValueMap中只有String类型的值那么content-type会被设置为`application/x-www-form-urlencoded`
## Http接口
Spring允许将Http service定义为java接口该方法上有注解用于http交换。可以通过该接口产生一个代理对象实现该接口代理对象可以执行http请求交换。
首先,定义一个接口,并且通过`@HttpExchange`注解来标注接口中的方法:
```java
interface RepositoryService {
@GetExchange("/repos/{owner}/{repo}")
Repository getRepository(@PathVariable String owner, @PathVariable String repo);
// more HTTP exchange methods...
}
```
其次可以创建一个代理对象来执行http请求创建方式如下所示
```java
WebClient client = WebClient.builder().baseUrl("https://api.github.com/").build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builder(WebClientAdapter.forClient(client)).build();
RepositoryService service = factory.createClient(RepositoryService.class);
```
`@HttpExchange`注解也支持类级别,类级别注解将会应用到接口中所有的方法:
```java
@HttpExchange(url = "/repos/{owner}/{repo}", accept = "application/vnd.github.v3+json")
interface RepositoryService {
@GetExchange
Repository getRepository(@PathVariable String owner, @PathVariable String repo);
@PatchExchange(contentType = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
void updateRepository(@PathVariable String owner, @PathVariable String repo,
@RequestParam String name, @RequestParam String description, @RequestParam String homepage);
}
```