当前位置: 首页 > article >正文

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;
    }
}


http://www.kler.cn/a/513200.html

相关文章:

  • 【大模型】ChatGPT 高效处理图片技巧使用详解
  • Low-Level 大一统:如何使用Diffusion Models完成视频超分、去雨、去雾、降噪等所有Low-Level 任务?
  • vue2 - Day05 - VueX
  • 【语言处理和机器学习】概述篇(基础小白入门篇)
  • 当PHP遇上区块链:一场奇妙的技术之旅
  • 前沿技术趋势洞察与分析:探寻科技变革的多维密码
  • 根据经纬度查询地理位置信息API
  • React技术栈搭配(全栈)(MERN栈、PERN栈)
  • [Css]父元素监听鼠标移入子元素
  • Kotlin 2.1.0 入门教程(七)
  • 若依报错:无法访问com.ruoyi.common.annotation
  • 微信小程序使用picker根据接口给的省市区的数据实现省市区三级联动或者省市区街道等多级联动
  • 在Android Studio中如何实现综合实验MP3播放器(保姆级教程)
  • Java学习,List 元素替换
  • 服务器安装ESXI7.0系统及通过离线包方式升级到ESXI8.0
  • Y3编辑器功能指引
  • Redis单线程为什么能这么快
  • grafana+prometheus监控linux指标
  • 美区TikTok解封后如何回归使用?
  • 软件授权产品介绍
  • 算法题目总结-栈和队列
  • 数据库基础知识:理论、E-R图、事务、原则
  • 【VOS源码解析-2024CVPR-Cutie】1、train_wrapper结构解析
  • sqlmap 自动注入 -01
  • 【Linux】华为服务器使用U盘安装统信操作系统
  • 跨境电商之小程序shinecrys水晶国度小程序数据分析