RestTemplate-调用远端接口应用场景

news/2025/1/22 12:11:39/

环境准备: Springboot项目
RestTemplate注入到项目中

java">	@Configurationpublic class Config {@Beanpublic RestTemplate restTemplate() {return new RestTemplate(new OkHttp3ClientHttpRequestFactory());}}

案例一: 使用get调用远程接口: 地址如: http://xxxx.xxx.xxx/xxx?a=111&b=222

客户端-接口调用:

java">    @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();}}

客户端-工具类

java">@Component
public class RestTemplateUtils {@Autowiredprivate 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体中获取参数)注解

java">     @GetMapping("/getData")public Map<String,Object> getData(@RequestParam Map<String,Object> map) {// 逻辑处理return map;}

案例二: 使用post调用远程接口: 入参为map, 接口返回map

客户端-接口调用:

java">   @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();}}

客户端-工具类:

java">@Component
public class RestTemplateUtils {@Autowiredprivate 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中

java">    @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

客户端-接口调用:

java">    @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();}}

客户端-工具类:

java">@Component
public class RestTemplateUtils {@Autowiredprivate static RestTemplate restTemplate;static {restTemplate = new RestTemplate();}public static Map<String,Object> postHttpServerFile(String uri, Map<String,Object> requestParams, List<File> files ){try{// 构建 MultiValueMapMultiValueMap<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 来映射接收

java">@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文件缓存到本地响应

java">    @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();}}

客户端-工具类:

java">@Component
public class RestTemplateUtils {@Autowiredprivate 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内,方便调用方使用

java">@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 {@Autowiredprivate 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{// 构建 MultiValueMapMultiValueMap<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;}
}

http://www.ppmy.cn/news/1565216.html

相关文章

html与css学习笔记(2)

一、CSS引入方式 具体有 3 种引入方式&#xff0c;语法如下表格所示&#xff1a; 引入方式语法内联样式在HTML标签中使用style属性&#xff0c;例如&#xff1a;<div style"color: red;">这是一个红色的div</div>内部样式表在HTML文件的<head>标签…

Django学习笔记(安装和环境配置)-01

Django学习笔记(安装和环境配置)-01 一、创建python环境 1、可以通过安装Anaconda来创建一个python环境 # 创建一个虚拟python环境 conda create -n django python3.8 # 切换激活到创建的环境中 activate django2、安装django # 进入虚拟环境中安装django框架 pip install …

Python 常用运维模块之Shutil 模块

Python 常用运维模块之Shutil 模块 Shutil 模块复制源文件到目标路径复制源文件权限到目标文件复制源文件的最近修改时间、权限等元信息到目标文件复制源文件到目标路径&#xff08;包含文件名&#xff09;复制源文件及相关元信息到目标路径移动文件或目录获取磁盘使用情况复制…

第01章 22 使用 vtkStructuredGrid 实现一个分形的树枝状几何体

以下是一个简单的示例&#xff0c;展示如何使用 vtkStructuredGrid 实现一个分形的树枝状几何体。我们将基于递归的分形算法生成树枝结构&#xff0c;并将其存储在 vtkStructuredGrid 中。 示例代码 #include <vtkSmartPointer.h> #include <vtkPoints.h> #includ…

【C++】引用(上)

1、引用的基本使用 作用&#xff1a;给变量起别名 语法&#xff1a;数据类型&#xff08;该数据类型要与原名的数据类型一致&#xff09; &别名原名&#xff1b; 示例&#xff1a; #include<iostream> using namespace std; int main() {int a 10;int& …

who w who

https://www.ityww.cn/733.html Linux查看用户登录信息命令-w & who & whoami Linux 基础 yvan 8年前 (2017-02-04) 3633次浏览 已收录 0个评论 显示当前已登录用户会话及动作命令-w 格式&#xff1a;w [options] [rootlocalhost ~]# w 23:46:39 up 8:29, 2 users, lo…

Linux:文件描述符fd、系统调用open

目录 一、文件基础认识 二、C语言操作文件的接口 1.> 和 >> 2.理解“当前路径” 三、相关系统调用 1.open 2.文件描述符 3.一切皆文件 4.再次理解重定向 一、文件基础认识 文件 内容 属性。换句话说&#xff0c;如果在电脑上新建了一个空白文档&#xff0…

场馆预定平台高并发时间段预定实现V2

&#x1f3af; 本文档介绍了场馆预订系统接口V2的设计与实现&#xff0c;旨在解决V1版本中库存数据不一致及性能瓶颈的问题。通过引入令牌机制确保缓存和数据库库存的最终一致性&#xff0c;避免因服务器故障导致的库存错误占用问题。同时&#xff0c;采用消息队列异步处理库存…