一、什么是RestTemplate
RestTemplate 是Spring框架提供的一个用于应用中调用REST服务的类。它简化了与HTTP服务的通信,统一了RESTFul的标准,并封装了HTTP连接,我们只需要传入URL及其返回值类型即可。RestTemplate的设计原则与许多其他Spring的模板类(如JdbcTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
二、RestTemplate 的常用方法
RestTemplate提供了多种方法来进行HTTP请求,主要方法包括:
1. GET请求:
- getForObject(String url, Class responseType, Object… uriVariables): 直接返回响应体中的数据。
- getForEntity(String url, Class responseType, Object… uriVariables): 返回一个ResponseEntity对象,其中包含了响应的详细信息,如状态码、响应头等。
2. POST请求:
- postForObject(String url, Object request, Class responseType): 发送POST请求,并返回响应体中的数据。
- postForEntity(String url, Object request, Class responseType): 发送POST请求,并返回一个ResponseEntity对象。
3. PUT请求:
- put(String url, Object request): 发送PUT请求。
- putForObject(String url, Object request, Class responseType): 发送PUT请求,并返回响应体中的数据。
4. DELETE请求:
- delete(String url): 发送DELETE请求。
其他方法: - exchange(RequestEntity<?> request, Class responseType): 这是一个通用的方法,可以根据RequestEntity对象发送请求,并返回ResponseEntity对象。
三、RestTemplate基本使用
1. pom 文件依赖
Spring Boot的 web starter 已经内置了RestTemplate的Bean,我们主需要将它引入到我们的Spring Context中,再进行下简单的配置就可以直接使用了。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
2. 配置 RestTemplate
(1)默认配置:
RestTemplate默认使用 SimpleClientHttpRequestFactory
,内部调用JDK的HttpURLConnection进行HTTP请求,默认的超时时间为-1(即无限期等待)。
@Configuration
public class RestClientConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
// 或者自定义请求工厂
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setReadTimeout(5000); // 设置读取超时时间
factory.setConnectTimeout(5000); // 设置连接超时时间
return new RestTemplate(factory);
}
}
(2)自定义配置:
可以通过设置ClientHttpRequestFactory来自定义RestTemplate的配置,如使用HttpComponentsClientHttpRequestFactory
(基于Apache HttpClient)或OkHttp3ClientHttpRequestFactory(基于OkHttp)等。
可以配置连接池、超时时间、请求和响应的编解码等。
@Configuration
public class RestTemplateConfig {
@Bean
public HttpClientConnectionManager poolingHttpClientConnectionManager() {
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
// 设置最大连接数
poolingHttpClientConnectionManager.setMaxTotal(500);
// 设置每个路由的最大连接数
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
return poolingHttpClientConnectionManager;
}
@Bean
public HttpClient httpClient(HttpClientConnectionManager poolingHttpClientConnectionManager) {
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
// 设置 HttpClient 的连接管理器
httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);
return httpClientBuilder.build();
}
@Bean
public ClientHttpRequestFactory clientHttpRequestFactory(HttpClient httpClient) {
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
// 设置 HttpClient
clientHttpRequestFactory.setHttpClient(httpClient);
// 设置连接超时时间(毫秒)
clientHttpRequestFactory.setConnectTimeout(5 * 1000);
// 设置读取超时时间(毫秒)
clientHttpRequestFactory.setReadTimeout(10 * 1000);
// 设置从连接池获取连接的超时时间(毫秒)
clientHttpRequestFactory.setConnectionRequestTimeout(10 * 1000);
return clientHttpRequestFactory;
}
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory clientHttpRequestFactory) {
RestTemplate restTemplate = new RestTemplate();
// 设置请求工厂
restTemplate.setRequestFactory(clientHttpRequestFactory);
return restTemplate;
}
}
四、服务端代码实战
1. 服务端接口类
@RestController
public class RestControllerDemo {
/**
* 普通Get
*
* @param name
* @return
*/
@GetMapping("/get")
private String getMethod(@RequestParam("name") String name) {
System.out.println("getMethod : name=" + name);
return name;
}
/**
* Restful Get
*
* @param name
* @return
*/
@GetMapping("/getName/{name}")
private String getRestName(@PathVariable("name") String name) {
System.out.println("getRestName : name=" + name);
return name;
}
/**
* post
*
* @param name
* @return
*/
@PostMapping("/post")
private String postMethod(@RequestParam("name") String name) {
System.out.println("postMethod : name=" + name);
return name;
}
/**
* post json
*
* @param stu
* @return
*/
@PostMapping("/postBody")
public String postBodyMethod(@RequestBody String stu) {
Student student = JSONObject.parseObject(stu, Student.class);
System.out.println("postBodyMethod : student=" + student);
return student.toString();
}
}
2. 测试类
@SpringBootTest
class DemoApplicationTests {
// 引入 restTemplate
@Resource
private RestTemplate restTemplate;
@Test
void getTest() {
String str = restTemplate.getForObject("http://localhost:8888/get?name=zs", String.class);
System.out.println(str);
}
@Test
void getRestTest() {
String name = "ls";
String str = restTemplate.getForObject("http://localhost:8888/getName/" + name, String.class);
System.out.println(str);
}
@Test
void postTest() {
LinkedMultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.set("name", "zs");
String str = restTemplate.postForObject("http://localhost:8888/post", map, String.class);
System.out.println(str);
}
@Test
void postBodyTest() {
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
headers.add("Accept", MediaType.APPLICATION_JSON.toString());
HashMap<String, Object> map = new HashMap<>();
map.put("name", "zs");
map.put("age", 23);
String stu = JSON.toJSONString(map);
HttpEntity<String> formEntity = new HttpEntity<String>(stu, headers);
String str = restTemplate.postForObject("http://localhost:8888/postBody", formEntity, String.class);
System.out.println(str);
}
}
3. exchange 使用示例
通过 HttpHeaders 和 UriComponentsBuilder 可以方便地添加自定义请求头和构建带参数的 URL。
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url)
.queryParam("param1", "value1")
.queryParam("param2", "value2");
String finalUrl = builder.toUriString();
HttpHeaders headers = new HttpHeaders();
headers.add("Custom-Header", "HeaderValue");
HttpEntity<String> request = new HttpEntity<>(null, headers);
ResponseEntity<String> response = restTemplate.exchange(
finalUrl,
HttpMethod.GET,
request,
String.class
);