Springboot中使用RestTemplate完成多文件上传

背景:现有Springboot微服务A,其对外提供一个多文件上传的接口,接口代码如下:

/**
* 远程服务提供的多文件上传的REST API
* @param files
* @param request
* @return
*/
@RequestMapping(value = "/file/upload", method = RequestMethod.POST)
public String uploadFile(@RequestParam("files") MultipartFile[] files, HttpServletRequest request) {
   if (ArrayUtils.isEmpty(files)) {
       logger.info("No file provided------");
       ret.put("status", CommonConstant.RES_FAILURE);
       ret.put("errorMsg", "请至少选择一个文件上传!");
       return ret.toJSONString();
   }
   // TODO 具体略
}

现在,我在Springboot微服务B中,需要调用服务A的文件上传接口,这里演示使用RestTemplate完成服务间的调用。参考代码如下:

  /**
   * 使用RestTemplate完成多文件上传
   * @param files
   * @param request
   * @return
   */
   public String uploadFile(MultipartFile[] files, HttpServletRequest request) {
		String tempPath = "E:\data\test\app\document";
		String uploadUrl = "http://localhost:9066/api/v1/file/upload";
		// 获取请求参数
		String type = request.getParameter("type");
		String id = request.getParameter("id");
		String ptnReference = request.getParameter("ptnReference");
		String chineseName = request.getParameter("chineseName");
		logger.info("Type is [{}], id is [{}], ptnRef is [{}], chineseName is [{}]----", type, id, ptnReference,
				chineseName);
		// 设置请求头
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.parseMediaType("multipart/form-data;charset=UTF-8"));
	
		MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
		List<String> tempList = new ArrayList<>(); // 保存临时文件
		for (MultipartFile file : files) {
			createDir(tempPath);
			String tempFilePath = tempPath + file.getOriginalFilename();
			try {
				// create local temp file
				FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(tempFilePath));
				tempList.add(tempFilePath); 
				// MultipartFile 直接转 FileSystemResource是不行的
				FileSystemResource resource = new FileSystemResource(tempFilePath); // 把临时文件变成FileSystemResource
				// LinkedMultiValueMap中,key对应的value值其实是一个LinkedList,所以可以一直往同一个key中add值,不会覆盖
				param.add("files", resource); 
			} catch (Exception e) {
				logger.error("保存文件{}至本地临时文件异常!", file.getOriginalFilename(), e);
			}
		}
		param.add("id", id);
		param.add("type", type);
		param.add("ptnReference", ptnReference);
		param.add("chineseName", chineseName);
		// 发送请求,这里的restTemplate是通过@Autowired注入的
		HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(param, headers);
		String result = restTemplate.postForObject(uploadUrl, formEntity, String.class);
		logger.info("ptnReference==[{}]的交易, 文件上传的结果===={}", ptnReference, result);
		// delete local temp file
		deleteLocalTempFiles(tempList);
		
		return result;
	}

	private void deleteLocalTempFiles(List<String> tempList) {
		if (!CollectionUtils.isEmpty(tempList)) {
			for (String fileName : tempList) {
				new File(fileName).delete();
			}
		}
	}
	
	private void createDir(String tempPath) {
		File file = new File(tempPath);
		if (!file.exists()) {
			file.mkdirs();
		}
	}

主要思路就是,现将文件转化为FileSystemResource,然后通过LinkedMultiValueMap来传递参数。

参考文档:https://www.baeldung.com/spring-rest-template-multipart-upload

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
文件分片上传是一种常见的上传大文件的方式,可以将大文件分成多个小文件进行上传,提高上传速度和稳定性。Springboot提供了restTemplate来方便地进行HTTP请求,可以使用restTemplate实现文件分片上传到第三方接口。 下面是一个简单的示例,用于将一个大文件分成多个小文件进行上传: 1.首先,需要确定每个文件分片的大小,以及总的分片数。可以使用文件长度和分片大小来计算总的分片数。 2.使用restTemplate发送HTTP请求,将每个分片上传到第三方接口。可以使用MultiValueMap来设置HTTP请求的参数,包括文件分片数据和其他参数。 3.在上传完成后,将所有分片上传的结果合并起来,判断是否上传成功。 以下是一个简单的示例代码: ```java public class FileUploadService { private RestTemplate restTemplate; public void uploadFile(String url, File file, int chunkSize) { long fileSize = file.length(); int totalChunks = (int) Math.ceil(fileSize / (double) chunkSize); String filename = file.getName(); String contentType = Files.probeContentType(file.toPath()); for (int chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) { int start = chunkIndex * chunkSize; int end = (int) Math.min(start + chunkSize, fileSize); byte[] chunkData = Files.readAllBytes(file.toPath()).subList(start, end).toArray(new byte[0]); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); MultiValueMap<String, Object> body = new LinkedMultiValueMap<>(); body.add("file", new ByteArrayResource(chunkData) { @Override public String getFilename() { return filename; } }); body.add("filename", filename); body.add("contentType", contentType); body.add("chunkIndex", chunkIndex); body.add("totalChunks", totalChunks); HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers); ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class); // handle response if (responseEntity.getStatusCode() != HttpStatus.OK) { throw new RuntimeException("File upload failed: " + responseEntity.getBody()); } } } } ``` 在上面的代码,我们使用了ByteArrayResource来表示文件分片的数据,同时设置了HTTP请求的其他参数,包括文件名、文件类型、分片索引和总的分片数。在上传完成后,我们可以根据所有分片上传的结果来判断上传是否成功。 请注意,上面的代码仅作为示例。实际使用时,还需要处理上传可能出现的异常和错误情况,以及进行适当的重试和恢复操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值