目录
2、使用HttpClient作为RestTemplate客户端
一、RestTemplate配置
1、将RestTemplate初始化为Bean
java
package com.xiaobai.conf;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
/**
* @Author 王天文
* @Date 2024/12/29 18:06
* @Description: RestTemplate配置类
*/
@Configuration
public class RestTemplateConf {
/**
* 当指定类型Bean不存在时,会创建一个新的Bean,如果用户自定义了Bean,将使用用户自定义的Bean
* @return
*/
@ConditionalOnMissingBean(RestTemplate.class)
@Bean
public RestTemplate restTemplate() {
// 使用JDK自带的HttpURLConnection作为客户端
RestTemplate restTemplate = new RestTemplate();
return restTemplate;
}
}
2、使用HttpClient作为RestTemplate客户端
(1)引入HttpClient依赖
XML
<!--httpclient-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
(2)修改RestTemplate配置类
java
package com.xiaobai.conf;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
/**
* @Author 王天文
* @Date 2024/12/29 18:06
* @Description: RestTemplate配置类
*/
@Configuration
public class RestTemplateConf {
/**
* 当指定类型Bean不存在时,会创建一个新的Bean,如果用户自定义了Bean,将使用用户自定义的Bean
* @return
*/
@ConditionalOnMissingBean(RestTemplate.class)
@Bean
public RestTemplate restTemplate() {
// 使用httpclient作为底层客户端
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
return restTemplate;
}
/**
* 使用httpclient作为底层客户端
* @return
*/
@Bean
public ClientHttpRequestFactory getClientHttpRequestFactory() {
int timeout = 50000;
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(timeout)
.setConnectionRequestTimeout(timeout)
.setSocketTimeout(timeout)
.build();
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
}
3、设置拦截器
(1)新增拦截器类
java
package com.xiaobai.conf;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.IOException;
/**
* @Author 王天文
* @Date 2024/12/22 21:51
* @Description: restTemplate拦截器
*/
public class RestTemplateInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest,
byte[] bytes,
ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
ClientHttpResponse httpResponse = clientHttpRequestExecution.execute(httpRequest, bytes);
return httpResponse;
}
}
(2)设置拦截器
java
package com.xiaobai.conf;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.util.Collections;
/**
* @Author 王天文
* @Date 2024/12/29 18:06
* @Description: RestTemplate配置类
*/
@Configuration
public class RestTemplateConf {
/**
* 当指定类型Bean不存在时,会创建一个新的Bean,如果用户自定义了Bean,将使用用户自定义的Bean
* @return
*/
@ConditionalOnMissingBean(RestTemplate.class)
@Bean
public RestTemplate restTemplate() {
// 使用JDK自带的HttpURLConnection作为客户端
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
// 设置拦截器
restTemplate.setInterceptors(Collections.singletonList(restTemplateInterceptor()));
return restTemplate;
}
/**
* 使用httpclient作为底层客户端
* @return
*/
@Bean
public ClientHttpRequestFactory getClientHttpRequestFactory() {
int timeout = 50000;
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(timeout)
.setConnectionRequestTimeout(timeout)
.setSocketTimeout(timeout)
.build();
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
/**
* 拦截器
* @return
*/
@Bean
public RestTemplateInterceptor restTemplateInterceptor() {
return new RestTemplateInterceptor();
}
}
4、新增支持的媒体类型
RestTemplate
只支持application/json
格式,需要手动补充text/plan,text/html
格式
java
package com.xiaobai.conf;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.Collections;
/**
* @Author 王天文
* @Date 2024/12/29 18:06
* @Description: RestTemplate配置类
*/
@Configuration
public class RestTemplateConf {
/**
* 当指定类型Bean不存在时,会创建一个新的Bean,如果用户自定义了Bean,将使用用户自定义的Bean
* @return
*/
@ConditionalOnMissingBean(RestTemplate.class)
@Bean
public RestTemplate restTemplate() {
// 使用JDK自带的HttpURLConnection作为客户端
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
// 设置拦截器
restTemplate.setInterceptors(Collections.singletonList(restTemplateInterceptor()));
// 增加支持的媒体类型
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter());
return restTemplate;
}
/**
* 使用httpclient作为底层客户端
* @return
*/
@Bean
public ClientHttpRequestFactory getClientHttpRequestFactory() {
int timeout = 50000;
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(timeout)
.setConnectionRequestTimeout(timeout)
.setSocketTimeout(timeout)
.build();
CloseableHttpClient httpClient = HttpClientBuilder.create()
.setDefaultRequestConfig(requestConfig)
.build();
return new HttpComponentsClientHttpRequestFactory(httpClient);
}
/**
* 拦截器
* @return
*/
@Bean
public RestTemplateInterceptor restTemplateInterceptor() {
return new RestTemplateInterceptor();
}
/**
* 媒体类型
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
// RestTemplate 只支持application/json格式,需要手动补充text/html格式
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.TEXT_PLAIN, MediaType.TEXT_HTML));
return mappingJackson2HttpMessageConverter;
}
}
二、RestTemplate使用
1、RestTemplate注入
java
@Autowired
private RestTemplate restTemplate;
2、无参数get请求测试
(1)Controller代码
java
@GetMapping(value = "/getString")
public String getString() {
return "操作成功";
}
(2)RestTemplate单元测试
java
@Test
public void testGetString() {
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8090/getString", String.class);
log.info(responseEntity.getBody());
}
3、带参get请求测试
(1)Controller代码
java
@GetMapping("/getRequestByParam")
public Map<String, Object> getRequestByParam(@RequestParam("name") String name) {
log.info("名称:" + name);
Map<String, Object> map = new HashMap<>();
map.put("responseData", "请求成功");
return map;
}
(2)RestTemplate单元测试
java
@Test
public void testParamGet() throws Exception {
Map<String, Object> param = new HashMap<>();
param.put("name", "张三");
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8090/getRequestByParam?name={name}", String.class, param);
log.info("响应信息:{}", responseEntity.getBody());
}
4、带占位符参数的get请求测试
(1)Controller代码
java
@GetMapping("/getRequestByPlaceHolder/{name}/{age}")
public Map<String, Object> getRequestByPlaceHolder(@PathVariable("name") String name,
@PathVariable("age") String age) {
log.info("名称:" + name);
log.info("年龄:" + age);
Map<String, Object> map = new HashMap<>();
map.put("responseData", "请求成功");
return map;
}
(2)RestTemplate单元测试
java
@Test
public void testPlaceholderGet() {
ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://localhost:8090/getRequestByPlaceHolder/{1}/{2}", String.class, "张三", "25");
log.info("响应信息:{}", responseEntity.getBody());
}
5、post请求测试
(1)Article实体类
java
package com.xiaobai.aroundtest.entity;
import lombok.Data;
import java.io.Serializable;
/**
* @author wangtw
* @date 2023/12/6 0:35
* @description
*/
@Data
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 文章名称
*/
private String name;
/**
* 描述
*/
private String description;
}
(2)Controller代码
java
@PostMapping("/postRequest")
public Map<String, Object> postRequest(@RequestParam String name, @RequestBody Article article) {
log.info("名称:" + name);
log.info("文章名称:" + article.getName());
log.info("文章描述:" + article.getDescription());
Map<String, Object> map = new HashMap<>();
map.put("responseData", "请求成功");
return map;
}
(3)RestTemplate单元测试
java
@Test
public void testPost() {
// 表单数据
Map<String, Object> formData = new HashMap<>();
formData.put("name", "解忧杂货店");
formData.put("description", "这是一本好书");
// 单独传参
Map<String, Object> param = new HashMap<>();
param.put("name", "东野圭吾");
// 请求调用
HttpEntity<Map<String, Object>> formEntity = new HttpEntity<>(formData);
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost:8090/postRequest?name={name}", formEntity, String.class, param);
log.info("响应信息:{}", responseEntity.getBody());
}
6、设置请求头
(1)Article实体类
java
package com.xiaobai.aroundtest.entity;
import lombok.Data;
import java.io.Serializable;
/**
* @author wangtw
* @date 2023/12/6 0:35
* @description
*/
@Data
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 文章名称
*/
private String name;
/**
* 描述
*/
private String description;
}
(2)Controller代码
java
@PostMapping("/postRequestHeader")
public Map<String, Object> postRequestHeader(HttpServletRequest request,
@RequestParam String name, @RequestBody Article article) {
String token = request.getHeader("token");
log.info("请求token:" + token);
log.info("名称:" + name);
log.info("文章名称:" + article.getName());
log.info("文章描述:" + article.getDescription());
Map<String, Object> map = new HashMap<>();
map.put("responseData", "请求成功");
return map;
}
(3)RestTemplate单元测试
java
@Test
public void testPostHeader() {
// 请求头
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("token", "123456");
// 表单数据
Map<String, Object> formData = new HashMap<>();
formData.put("name", "解忧杂货店");
formData.put("description", "这是一本好书");
// 单独传参
Map<String, Object> param = new HashMap<>();
param.put("name", "东野圭吾");
// 请求调用
HttpEntity<Map<String, Object>> formEntity = new HttpEntity<>(formData, httpHeaders);
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost:8090/postRequestHeader?name={name}", formEntity, String.class, param);
log.info("响应信息:{}", responseEntity.getBody());
}
7、上传文件
(1)Controller代码
java
@PostMapping("/upload")
public Map<String, Object> upload(@RequestParam String name, MultipartFile uploadFile) throws IOException {
log.info("名称:" + name);
uploadFile.transferTo(new File("D:\\temp/" + uploadFile.getOriginalFilename()));
Map<String, Object> map = new HashMap<>();
map.put("responseData", "请求成功");
return map;
}
(2)RestTemplate单元测试
java
@Test
public void testUploadFile() {
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("uploadFile", new FileSystemResource(new File("D:\\christmas-tree.svg")));
param.add("name", "张三");
// 请求头设置
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
// 请求调用
HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(param, headers);
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://localhost:8090/upload", formEntity, String.class);
log.info("响应信息:{}", responseEntity.getBody());
}
8、文件下载
(1)Controller代码
java
@PostMapping("/download")
public Map<String, Object> download(@RequestParam String fileName,
HttpServletResponse response) {
log.info("文件名称:" + fileName);
File file = new File("D:\\temp/" + fileName);
try(FileInputStream fileInputStream = new FileInputStream(file);
ServletOutputStream outputStream = response.getOutputStream()) {
response.setHeader("content-disposition","attachment;fileName=" + URLEncoder.encode(fileName,"UTF-8"));
FileCopyUtils.copy(fileInputStream, outputStream);
} catch (Exception e) {
e.printStackTrace();
}
Map<String, Object> map = new HashMap<>();
map.put("responseData", "请求成功");
return map;
}
(2)RestTemplate单元测试
java
@Test
public void testDownloadFile() {
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("fileName", "christmas-tree.svg");
// 请求调用
HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(param);
ResponseEntity<byte[]> responseEntity = restTemplate.postForEntity("http://localhost:8090/download", formEntity, byte[].class);
// 获取响应头
HttpHeaders responseEntityHeaders = responseEntity.getHeaders();
Set<Map.Entry<String, List<String>>> responseSet = responseEntityHeaders.entrySet();
for (Map.Entry<String, List<String>> responseValue : responseSet) {
log.info("响应头:" + responseValue.getKey() + ",响应内容:" + responseValue.getValue());
}
try {
// 文件保存
byte[] fileData = responseEntity.getBody();
FileCopyUtils.copy(fileData, new File("D:\\christmas-tree1.svg"));
} catch (IOException e) {
e.printStackTrace();
}
}