RestTemplate-调用远端接口应用场景
环境准备: Springboot项目
RestTemplate注入到项目中
@Configuration
public class Config {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate(new OkHttp3ClientHttpRequestFactory());
}
}
案例一: 使用get调用远程接口: 地址如: http://xxxx.xxx.xxx/xxx?a=111&b=222
客户端-接口调用:
@GetMapping("/test")
public void getTest(){
try{
System.out.println("模拟get请求: map参数会追加到url后, 如: http://xxx?text=aaa&test2=bbb");
Map<String,String> map = new HashMap<>();
map.put("test","123");
Map<String, Object> httpServer = RestTemplateUtils.getHttpServer("http://10.24.100.105:8080/request/getData", map);
System.out.println("httpServer==>" + httpServer);
}catch (Exception e) {
e.printStackTrace();
}
}
客户端-工具类
@Component
public class RestTemplateUtils {
@Autowired
private static RestTemplate restTemplate;
static {
restTemplate = new RestTemplate();
}
public static Map<String,Object> getHttpServer(String baseUrl, Map<String, String> requestParams){
Map<String,Object> responseBody = new HashMap<>();
try{
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
requestParams.forEach((key, value) -> body.add(key, value));
// 使用 UriComponentsBuilder 构建 URL,包含查询参数
String url = UriComponentsBuilder.fromHttpUrl(baseUrl)
.queryParams(body)
.toUriString();
// 发送 GET 请求并获取响应体(假设响应体是 JSON 格式)
String response = restTemplate.getForObject(url, String.class);
// 解析 JSON 响应为 Map(这里省略了错误处理逻辑)
ObjectMapper objectMapper = new ObjectMapper();
responseBody = objectMapper.readValue(response, HashMap.class);
} catch (Exception e){
e.printStackTrace();
}
return responseBody;
}
}
服务端-接口提供:
由于参数在url后面所以.服务端在接收参数时需用@RequestParam
(从url上获取参数)注解,而不是用@RequestBody
(从body体中获取参数)注解
@GetMapping("/getData")
public Map<String,Object> getData(@RequestParam Map<String,Object> map) {
// 逻辑处理
return map;
}
案例二: 使用post调用远程接口: 入参为map, 接口返回map
客户端-接口调用:
@GetMapping("/test")
public void getTest(){
try{
System.out.println("模拟post请求: 入参map,出参map");
Map<String,Object> map2 = new HashMap<>();
map2.put("test","123");
Map<String, Object> postServer= RestTemplateUtils.postHttpServer("http://10.24.100.105:8080/request/postData", map2);
System.out.println("postServer==>" + postServer);
}catch (Exception e) {
e.printStackTrace();
}
}
客户端-工具类:
@Component
public class RestTemplateUtils {
@Autowired
private static RestTemplate restTemplate;
static {
restTemplate = new RestTemplate();
}
public static Map<String,Object> postHttpServer(String uri, Map<String,Object> requestParams){
try{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity(requestParams,headers);
ResponseEntity<Map> response = restTemplate.exchange(uri, HttpMethod.POST, entity, Map.class);
Map<String,Object> body = response.getBody();
return body;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}
服务端-接口提供:
此时直接用@RequestBody
将入参映射到map中
@PostMapping("/postData")
public Map<String,Object> postData(@RequestBody Map<String,Object> map) {
map.put("request methods:","postData");
return map;
}
案例三: 使用post调用远程接口: 入参为map+file流文件, 接口返回map
在配置文件中添加如下属性: 防止报错The field files exceeds its maximum permitted size of 1048576 bytes.
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB
客户端-接口调用:
@GetMapping("/test")
public void getTest(){
try{
System.out.println("模拟post请求: 入参map + file文件,出参map");
Map<String,Object> map3 = new HashMap<>();
map3.put("test","123");
Map<String, Object> postfile= RestTemplateUtils.postHttpServerFile(postfileuri, map3,
Arrays.asList(new File("C:\\Users\\admin\\Desktop\\Docker安装mysql.docx")
));
System.out.println("postfile" + postfile);
}catch (Exception e) {
e.printStackTrace();
}
}
客户端-工具类:
@Component
public class RestTemplateUtils {
@Autowired
private static RestTemplate restTemplate;
static {
restTemplate = new RestTemplate();
}
public static Map<String,Object> postHttpServerFile(String uri, Map<String,Object> requestParams, List<File> files ){
try{
// 构建 MultiValueMap
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// 添加文件
for (int i = 0; i < files.size(); i++) {
FileSystemResource fileResource = new FileSystemResource(files.get(i));
body.add("file", fileResource);
}
// 将参数添加到MultiValueMap体内
requestParams.forEach((key, value) -> body.add(key, value));
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
// 创建 HttpEntity,使用 MultiValueMap 作为请求体
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity(body,headers);
// 发送请求,并获取响应
ResponseEntity<Map> response = restTemplate.exchange(uri, HttpMethod.POST, entity, Map.class);
Map<String,Object> responseBody = response.getBody();
return responseBody;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
}
服务端-接口提供:
这里的file文件和参数都需要用@RequestParam
来映射接收
@PostMapping("/postDatafile")
public Map<String,Object> postData(@RequestParam("file") MultipartFile[] file, @RequestParam Map<String,Object> map) {
map.put("request methods:","postDatafile");
map.put("fileName",file[0].getName());
map.put("getBytes",file[0].getSize());
return map;
}
案例四: 使用post调用远程接口: 入参为map, 接口返回map+file流文件
客户端:
客户端-接口调用:
请求远端地址, 并将返回的file文件缓存到本地响应
@GetMapping("/test")
public void getTest(){
System.out.println("模拟post请求: 入参map,出参file");
Map<String,Object> queryParam = new HashMap<>();
queryParam.put("id","123");
File file = RestTemplateUtils.postHttpServerGetFile("http://10.24.146.105:8080/request/downloadFile", queryParam);
// 将file写入到本地,
// 创建File对象表示目标文件
File targetFile = new File("C:\\Users\\admin\\Desktop\\test\\" + file.getName());
try (
// 创建输入流读取源文件
FileInputStream fis = new FileInputStream(file);
// 创建输出流写入目标文件
FileOutputStream fos = new FileOutputStream(targetFile);
) {
// 缓冲区
byte[] buffer = new byte[1024];
int bytesRead;
// 循环读取源文件内容并写入目标文件
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
System.out.println("文件已成功复制到目标目录。");
} catch (IOException e) {
e.printStackTrace();
}
}catch (Exception e) {
e.printStackTrace();
}
}
客户端-工具类:
@Component
public class RestTemplateUtils {
@Autowired
private static RestTemplate restTemplate;
static {
restTemplate = new RestTemplate();
}
/**
* post请求远端接口返回File
* @param uri
* @param requestParams
* @return file
*/
public static File postHttpServerGetFile(String uri, Map<String,Object> requestParams){
File tempFile = null;
try{
HttpHeaders headers = new HttpHeaders();
HttpEntity entity = new HttpEntity(requestParams,headers);
ResponseEntity<Resource> response = restTemplate.exchange(uri, HttpMethod.POST, entity, Resource.class);
// 检查响应状态码
if (response.getStatusCode().is2xxSuccessful()) {
Resource resource = response.getBody();
try (InputStream inputStream = resource.getInputStream()) {
// 提取文件名
String fileName = resource.getFilename();
if (fileName != null && !fileName.isEmpty()) {
tempFile = new File(URLDecoder.decode(fileName, "UTF-8"));
tempFile.deleteOnExit(); // JVM退出时删除临时文件
// 将输入流写入到临时文件中
try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
// 处理错误响应
System.err.println("Request failed with status code: " + response.getStatusCode());
}
} catch(Exception e) {
e.printStackTrace();
}
return tempFile;
}
}
服务端-接口提供:
服务器端设置一个文件, 需要将文件名称设置的headers内,方便调用方使用
@PostMapping("/downloadFile")
public ResponseEntity<InputStreamResource> downloadfile(@RequestBody Map<String,Object> map) {
try{
// 在这里,你可以根据传入的参数 params 来生成或获取文件内容
System.out.println("入参:" + map);
// 例如,你可以根据参数来查询数据库,获取文件的字节数据,或者生成一个新的文件
// 为了演示,我们引入了一个本地文件流
File file = new File("C:\\Users\\admin\\Desktop\\Docker安装mysql.docx");
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + URLEncoder.encode(file.getName(), "UTF-8") + "\"");
headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"));
// 创建响应实体
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return new ResponseEntity<>(resource, headers, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
完整代码:工具类
package com.ht.common.utils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.*;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 链接远端接口
*/
@Component
public class RestTemplateUtils {
@Autowired
private static RestTemplate restTemplate;
static {
restTemplate = new RestTemplate();
}
/**
* get请求,入参是map,出参也是map, 由于是get请求,没有请求体,参数会被封装到url后面
* @param baseUrl
* @param requestParams
* @return
*/
public static Map<String,Object> getHttpServer(String baseUrl, Map<String, String> requestParams){
Map<String,Object> responseBody = new HashMap<>();
try{
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
requestParams.forEach((key, value) -> body.add(key, value));
// 使用 UriComponentsBuilder 构建 URL,包含查询参数
String url = UriComponentsBuilder.fromHttpUrl(baseUrl)
.queryParams(body)
.toUriString();
// 发送 GET 请求并获取响应体(假设响应体是 JSON 格式)
String response = restTemplate.getForObject(url, String.class);
// 解析 JSON 响应为 Map(这里省略了错误处理逻辑)
ObjectMapper objectMapper = new ObjectMapper();
responseBody = objectMapper.readValue(response, HashMap.class);
} catch (Exception e){
e.printStackTrace();
}
return responseBody;
}
/**
* get请求: 参数会封装在HttpEntity
* @param baseUrl http://xxx
* @param requestParams 请求参数
* @return map
*/
public static Map<String,Object> getHttpServer2(String baseUrl, Map<String, String> requestParams){
try{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity(requestParams,headers);
ResponseEntity<Map> response = restTemplate.exchange(baseUrl, HttpMethod.GET, entity, Map.class);
Map<String,Object> body = response.getBody();
return body;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
/**
* http post请求
* @param uri 远程地址
* @param requestParams 请求参数
* @return 返回值
*
服务端接口定义
@PostMapping("/add")
public Map<String,Object> add(@RequestBody Map<String,Object> map) {
// 程序处理
return new HashMap();
}
*/
public static Map<String,Object> postHttpServer(String uri, Map<String,Object> requestParams){
try{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity entity = new HttpEntity(requestParams,headers);
ResponseEntity<Map> response = restTemplate.exchange(uri, HttpMethod.POST, entity, Map.class);
Map<String,Object> body = response.getBody();
return body;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
/**
* http post请求,携带多个文件+请求参数
* @param uri 远程地址
* @param requestParams 请求参数
* @param files 文件对象
* @return 返回值
服务端接口写法:
@PostMapping("/postDatafile")
public Map<String,Object> postData(@RequestParam("file") MultipartFile[] file, @RequestParam Map<String,Object> map) {
map.put("request methods:","postDatafile");
map.put("fileName",file[0].getName());
map.put("getBytes",file[0].getSize());
return map;
}
*/
public static Map<String,Object> postHttpServerFile(String uri, Map<String,Object> requestParams, List<File> files ){
try{
// 构建 MultiValueMap
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
// 添加文件
for (int i = 0; i < files.size(); i++) {
FileSystemResource fileResource = new FileSystemResource(files.get(i));
body.add("files", fileResource);
}
// 将参数添加到MultiValueMap体内
requestParams.forEach((key, value) -> body.add(key, value));
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
// 创建 HttpEntity,使用 MultiValueMap 作为请求体
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity(body,headers);
// 发送请求,并获取响应
ResponseEntity<Map> response = restTemplate.exchange(uri, HttpMethod.POST, entity, Map.class);
Map<String,Object> responseBody = response.getBody();
return responseBody;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
/**
* post请求远端接口返回File
* @param uri
* @param requestParams
* @return file
*/
public static File postHttpServerGetFile(String uri, Map<String,Object> requestParams){
File tempFile = null;
try{
HttpHeaders headers = new HttpHeaders();
HttpEntity entity = new HttpEntity(requestParams,headers);
ResponseEntity<Resource> response = restTemplate.exchange(uri, HttpMethod.POST, entity, Resource.class);
// 检查响应状态码
if (response.getStatusCode().is2xxSuccessful()) {
Resource resource = response.getBody();
try (InputStream inputStream = resource.getInputStream()) {
// 提取文件名
String fileName = resource.getFilename();
if (fileName != null && !fileName.isEmpty()) {
tempFile = new File(URLDecoder.decode(fileName, "UTF-8"));
tempFile.deleteOnExit(); // JVM退出时删除临时文件
// 将输入流写入到临时文件中
try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
// 处理错误响应
System.err.println("Request failed with status code: " + response.getStatusCode());
}
} catch(Exception e) {
e.printStackTrace();
}
return tempFile;
}
}