直接上代码
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>