java 根据路径下载文件转换为MultipartFile,并且上传到服务器

直接上代码
controller层

复制代码
	@GetMapping("/downloadAndUploadAttachment")
	@UpdateOperationLogging(msg = "根据路径下载文件转换为MultipartFile,并且上传到服务器")
	@Operation(summary = "根据路径下载文件转换为MultipartFile,并且上传到服务器", description = "根据路径下载文件转换为MultipartFile,并且上传到服务器")
	public R<Integer> downloadAndUploadAttachment() throws IOException {
		//第一个参数是一个类似于文件的存储路径,在浏览器输入可以直接下载,第二个参数是文件名称
//		String url = externalFileService.downloadAndUploadAttachment("https://attachmentgw.trinasolar.com/fs/ts/q8sc1zw9veq5fays2bo2sd8e/20241015/3A75DBB77A6649ACB1657710D822ED21.xlsx", "新建 Microsoft Excel 工作表.xlsx");
		String url = externalFileService.downloadAndUploadAttachment("https://attachmentgw.trinasolar.com/fs/ts/q8sc1zw9veq5fays2bo2sd8e/20241015/9AEE920F274947E392554EFB49BFC31E.jpeg", "2024-09-24_084333.jpeg");
		//打印返回的路径在浏览器也是可以直接下载(这样主要是解决一个跨域问题)
		System.out.println(url);
		return null;
	}

service层

复制代码
package com.trinasolar.admin.service.impl;


import com.hccake.ballcat.common.model.result.R;
import com.trinasolar.admin.controller.UploadController;
import com.trinasolar.devops.file.core.exception.UploadFailedException;
import com.trinasolar.devops.file.core.exception.UserTokenFetchIllegalExeption;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
@Service
@Slf4j
public class ExternalFileService {


	@Autowired
	UploadController uploadController;




	/**
	 * 从外部URL下载文件,并将其上传到服务器。
	 *
	 * @param externalFileUrl 外部文件的URL
	 * @param fileName 文件名
	 * @throws IOException 如果下载或读取文件时发生IO异常
	 */
	public String downloadAndUploadAttachment(String externalFileUrl, String fileName) throws IOException {
		try (CloseableHttpClient httpClient = createIgnoreSSLClient()) { // 创建一个忽略SSL验证的HTTP客户端
			HttpGet httpGet = new HttpGet(externalFileUrl); // 创建GET请求
			try (CloseableHttpResponse response = httpClient.execute(httpGet)) { // 执行GET请求
				if (response.getStatusLine().getStatusCode() == 200) { // 检查响应状态码是否为200
					InputStream inputStream = response.getEntity().getContent(); // 获取响应内容的输入流
					Path tempFile = Files.createTempFile("attachment", ""); // 创建临时文件
					Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING); // 将输入流写入临时文件

					// 创建MultipartFile对象
					MultipartFile multipartFile = createMultipartFile(tempFile, fileName);

					// 上传文件
					R<Map> uploadResult = uploadController.upload(multipartFile);
					return (String) uploadResult.getData().get("url");
				} else {
					throw new RuntimeException("Failed to download file: " + response.getStatusLine());
				}
			}
		} catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException e) {
			log.error("Failed to create HTTP client with ignored SSL", e);
			throw new RuntimeException("Failed to create HTTP client with ignored SSL", e);
		} catch (UploadFailedException | UserTokenFetchIllegalExeption e) {
			log.error("Failed to upload file", e);
			throw new RuntimeException("Failed to upload file", e);
		} catch (IOException e) {
			log.error("IO error occurred", e);
			throw new RuntimeException("IO error occurred", e);
		}
	}

	/**
	 * 创建忽略SSL验证的HTTP客户端
	 *
	 * @return 忽略SSL验证的HTTP客户端
	 * @throws KeyStoreException 如果密钥库操作失败
	 * @throws NoSuchAlgorithmException 如果找不到算法
	 * @throws KeyManagementException 如果密钥管理操作失败
	 */
	private CloseableHttpClient createIgnoreSSLClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
		SSLContext sslContext = SSLContextBuilder.create()
				.loadTrustMaterial(null, (chain, authType) -> true) // 信任所有证书
				.build();

		SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);

		return HttpClients.custom()
				.setSSLSocketFactory(sslSocketFactory)
				.build();
	}

	/**
	 * 创建MultipartFile对象
	 *
	 * @param tempFile 临时文件路径
	 * @param fileName 文件名
	 * @return MultipartFile对象
	 * @throws IOException 如果读取文件时发生IO异常
	 */
	private MultipartFile createMultipartFile(Path tempFile, String fileName) throws IOException {
		FileItemFactory factory = new DiskFileItemFactory();
		FileItem fileItem = factory.createItem("file", "application/octet-stream", true, fileName);
		fileItem.getOutputStream().write(Files.readAllBytes(tempFile));
		fileItem.getOutputStream().close();

		return new org.springframework.web.multipart.commons.CommonsMultipartFile(fileItem);
	}
}

上传文件的方法,这里上传大家作为一个参考即可,
是引用了公司的一个依赖

上传是使用公司的依赖

复制代码
<dependency>
	<groupId>com.trinasolar.devops.file</groupId>
	<artifactId>file-spring-boot-starter</artifactId>
	<version>1.0.0.1-SNAPSHOT</version>
</dependency>

@RestController
@RequestMapping("/upload")
@Tag(name = "文件服务上传")
public class UploadController {

	private final Uploader uploader;

	public UploadController(Uploader uploader) {
		this.uploader = uploader;
	}

	@PostMapping("/uploadFile")
	public R<Map> upload(MultipartFile file) throws UserTokenFetchIllegalExeption, IOException, UploadFailedException {
		String fileUrl = this.uploader.Upload(file);
		String replace = fileUrl.replace("http", "https");
		Map<String, String> map = new HashMap<>();
		map.put("name", file.getOriginalFilename());
		map.put("url", replace);
		return R.ok(map);
	}

}

该过程使用的全部依赖

复制代码
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.13</version> <!-- 或最新版本 -->
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.4</version> <!-- 或最新版本 -->
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.11.0</version> <!-- 或最新版本 -->
		</dependency>
相关推荐
RS迷途小书童1 分钟前
Python 解析大疆无人机 SRT 字幕日志
开发语言·python·无人机
我不会起名字32211 分钟前
一天一道算法题(29):单调栈
java·数据结构·python·算法·leetcode·golang·单调栈
XR12345678818 分钟前
医院移动医护零漫游无线网络选型指南
java·后端·struts
点心的游戏开发世界28 分钟前
GDScript 入门笔记(十六):文件读写与数据持久化
开发语言·笔记·游戏引擎·godot
干到60岁退休的码农29 分钟前
13.构建登录接口响应数据
java·spring boot·mybatis
会飞的拖把36 分钟前
Python序列详解:列表、元组、字符串的通用操作(超详细版)
开发语言·windows·python
水巷石子36 分钟前
学习langChain4j的第二天,体验springBoot中的starter
java·spring boot·学习·spring·langchain4j
ly768941 分钟前
Spring Bean生命周期全流程:从BeanDefinition到销毁
java·后端·spring·bean生命周期·beandefinition·初始化回调
reasonsummer1 小时前
【办公类-115-01】20260906育儿知识(家园小报)批量制作(2026年9月-2027年6月)
开发语言·数据库·c#