环境准备: 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;}
}