springboot中Controller內(nèi)文件上傳到本地及阿里云操作方法
上傳文件的基本操作

<form action="/upload" method="post" enctype="multipart/form-data">
<h1>登錄</h1>
姓名:<input type="text" name="username" required><br>
年齡:<input type="text" name="age" required><br>
頭像:<input type="file" name="file" required><br>
<input type="submit" value="提交">
</form> // Java接收前端發(fā)來(lái)的文件
@RestController
public class UploadController {
private static final ch.qos.logback.classic.Logger log = (Logger) LoggerFactory.getLogger(UploadController.class);
@PostMapping(path = "/upload")
public Result upload(String username, Integer age, MultipartFile file){
log.info("接收參數(shù):" + username + age + file);
return Result.success();
}
}注意:springboot項(xiàng)目啟動(dòng)后,打開(kāi)這個(gè)index.html的頁(yè)面要輸入:localhost:8080/index.html

接下來(lái)通過(guò)斷點(diǎn)調(diào)試獲取查看前端發(fā)送過(guò)來(lái)的文件

文件的”到此一游“:該文件所在的路徑的文件夾是個(gè)臨時(shí)文件夾,運(yùn)行完畢后這個(gè)文件夾里的內(nèi)容清空

前端上傳文件本地存儲(chǔ)
@PostMapping("/upload")
public Result upload(String name, Integer age, MultipartFile file) throws IOException {
// 記錄接收到的參數(shù),包括姓名、年齡和文件
log.info("接收參數(shù): {}, {}, {}", name, age, file);
// 獲取上傳文件的原始文件名
String originalFilename = file.getOriginalFilename();
// 將文件保存到指定路徑(D:/images/)并命名為原始文件名
file.transferTo(new File( "D:/idea/javacode/web/Getdata/" + originalFilename));
// 返回成功結(jié)果
return Result.success();
}文件上傳還存在一個(gè)要考慮的問(wèn)題:如果兩次提交的是不一樣的文件,但是文件名稱一樣,那么第二次提交的圖片會(huì)把第一次提交的文件給替換(覆蓋)因此可以使用UUID命名來(lái)解決。
生成UUID
import java.util.UUID;
public class UUIDExample {
public static void main(String[] args) {
// 生成一個(gè)隨機(jī)UUID
UUID uuid = UUID.randomUUID();
// 輸出UUID
System.out.println("生成的UUID: " + uuid.toString());
}
}使用UUID解決以上問(wèn)題
@PostMapping("/upload")
public Result upload(String name, Integer age, MultipartFile file) throws IOException {
// 記錄接收到的參數(shù),包括姓名、年齡和文件
log.info("接收參數(shù): {}, {}, {}", name, age, file);
// 獲取上傳文件的原始文件名,例如 "1.jpg" 或 "22.2.2.2.png"
String originalFilename = file.getOriginalFilename();
// 獲取文件擴(kuò)展名,從最后一個(gè)點(diǎn)后開(kāi)始截取
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
// 生成新的文件名,使用UUID并加上文件擴(kuò)展名
String newFileName = UUID.randomUUID().toString() + extension;
// 將文件保存到指定路徑(D:/images/)并命名為新的文件名
file.transferTo(new File("D:/images/" + newFileName));
// 返回成功結(jié)果
return Result.success();
}file.transferTo(new File("D:/idea/javacode/web/Getdata/" + newFileName));這個(gè)代碼的路徑最后一定要寫個(gè)“/”,使得文件保存在那個(gè)文件夾下。
上傳文件大小限制
默認(rèn)上傳文件的最大大小為1MB,超過(guò)該大小需要在配置文件配置
servlet:
multipart:
# 最大單個(gè)文件大小
max-file-size: 10MB
# 最大請(qǐng)求大小(包括所有文件和表單數(shù)據(jù))
max-request-size: 100MB
阿里云OSS
阿里云對(duì)象存儲(chǔ)oss(object Storage Service),是一款海量、安全、低成本、高可靠的云存儲(chǔ)服務(wù)。使用oss
您可以通過(guò)網(wǎng)絡(luò)隨時(shí)存儲(chǔ)和調(diào)用包括文本、圖片、音頻和視頻等在內(nèi)的各種文件。
具體怎么配看:視頻
配置好相關(guān)密鑰等配置后,創(chuàng)建bucket。接下來(lái)可以通過(guò)Java代碼將自己電腦本地的文件上傳到阿里云。
添加好下面的依賴
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.4</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>具體的上傳文件的代碼
public static void main(String[] args) throws com.aliyuncs.exceptions.ClientException {
/**
* 基礎(chǔ)配置:連接服務(wù)并驗(yàn)證個(gè)人身份
*/
// Endpoint以華東1(杭州)為例,其它Region請(qǐng)按實(shí)際情況填寫。
String endpoint = "https://oss-cn-shenzhen.aliyuncs.com";
// 從環(huán)境變量中獲取訪問(wèn)憑證。運(yùn)行本代碼示例之前,請(qǐng)確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫B(tài)ucket名稱,例如examplebucket。
String bucketName = "q-buckets";
/**
* 配置具體文件上傳信息
*/
// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
String objectName = "ph.webp"; // 可以修改名字
// 填寫本地文件的完整路徑,例如D:\\localpath\\examplefile.txt。
// 如果未指定本地路徑,則默認(rèn)從示例程序所屬項(xiàng)目對(duì)應(yīng)本地路徑中上傳文件。
String filePath= "D:\\Mycode\\webcode\\imag\\nu.webp";
// 創(chuàng)建OSSClient實(shí)例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// 創(chuàng)建PutObjectRequest對(duì)象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath));
// 如果需要上傳時(shí)設(shè)置存儲(chǔ)類型和訪問(wèn)權(quán)限,請(qǐng)參考以下示例代碼。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);
// 上傳文件。
PutObjectResult result = ossClient.putObject(putObjectRequest);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}這樣就可以在自己阿里云的bucket里面看到上傳的文件

參考:后端之路
文件上傳操作整合為工具類并在Controller中使用
具體代碼如下
@Component // 方便依賴注入
public class AliyunOSSOperation {
// 指定阿里云OSS的服務(wù)地址,這里是深圳區(qū)域的地址
private String endpoint = "https://oss-cn-shenzhen.aliyuncs.com";
// 指定要上傳到的存儲(chǔ)桶名稱
private String bucketName = "lwq-buckets";
// 指定阿里云的區(qū)域,這里是深圳區(qū)域
private String region = "cn-shenzhen";
/**
* 上傳文件到阿里云OSS
* @param content 文件的字節(jié)數(shù)組內(nèi)容
* @param originalFilename 原始文件名,用于生成新的文件名
* @return 上傳后文件的訪問(wèn)路徑
* @throws Exception 可能拋出的異常
*/
public String upload(byte[] content, String originalFilename) throws Exception {
// 從環(huán)境變量中獲取訪問(wèn)密鑰,確保在運(yùn)行代碼前設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET
EnvironmentVariableCredentialsProvider credentialsProvider =
CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 獲取object對(duì)象路徑,例如2024/06/21.png。Object類型中不能包含Bucket名稱
String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
// 生成一個(gè)新的文件名,使用UUID確保唯一性,并保留原始文件的擴(kuò)展名
String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
String objectName = dir + "/" + newFileName; // 生成完整的對(duì)象名稱
// 創(chuàng)建OSSClient實(shí)例
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // 設(shè)置簽名版本為V4
// 使用OSSClientBuilder創(chuàng)建OSS客戶端實(shí)例,配置包括端點(diǎn)、憑證提供者、客戶端配置和區(qū)域
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// 上傳文件內(nèi)容到指定的存儲(chǔ)桶和對(duì)象路徑
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
} finally {
// 確保無(wú)論上傳是否成功,都會(huì)關(guān)閉OSS客戶端
ossClient.shutdown();
}
// 生成并返回文件的完整訪問(wèn)路徑
return endpoint.split("http://")[0] + "http://" + bucketName + "." + endpoint.split("http://")[1] + "/" + objectName;
}
}使用該類
@Autowired // 自動(dòng)注入AliyunOSSOperator實(shí)例
private AliyunOSSOperator aliyunOSSOperator;
@PostMapping("/upload") // 定義一個(gè)POST請(qǐng)求處理方法,映射到/upload路徑
public Result upload(MultipartFile file) throws Exception {
// 記錄上傳文件的原始文件名到日志
log.info("文件上傳: {}", file.getOriginalFilename());
// 調(diào)用aliyunOSSOperator的upload方法,將文件字節(jié)和文件名上傳到OSS
String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());
// 記錄文件上傳后返回的URL到日志
log.info("文件上傳OSS, url: {}", url);
// 返回上傳結(jié)果,包含文件的訪問(wèn)URL
return Result.success(url);
}這樣上傳到阿里云的文件以年月劃分了文件夾

參數(shù)配置進(jìn)一步優(yōu)化
指將一些需要靈活變化的參數(shù),配置在配置文件中,然后通過(guò) @Value 注解來(lái)注入外部配置的屬性。
aliyun:
oss:
endpoint: https://oss-cn-beijing.aliyuncs.com
bucketName: java-ai
region: cn-beijing以上配置信息配置在yml文件中
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.bucketName}")
private String bucketName;
@Value("${aliyun.oss.region}")
private String region; 到此這篇關(guān)于springboot中Controller內(nèi)文件上傳到本地及阿里云操作方法的文章就介紹到這了,更多相關(guān)springboot Controller文件上傳內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot如何實(shí)現(xiàn)調(diào)用controller和Service層方法
- springboot中的controller參數(shù)映射問(wèn)題小結(jié)
- springboot如何通過(guò)controller層實(shí)現(xiàn)頁(yè)面切換
- springboot Controller直接返回String類型帶來(lái)的亂碼問(wèn)題及解決
- SpringBoot之controller參數(shù)校驗(yàn)詳解
- springboot中@RestController注解實(shí)現(xiàn)
- SpringBoot通過(guò)注解監(jiān)測(cè)Controller接口的代碼示例
- springboot controller參數(shù)注入方式
- SpringBoot中@RestControllerAdvice @ExceptionHandler異常統(tǒng)一處理類失效原因分析
- SpringBoot和MybatisPlus實(shí)現(xiàn)通用Controller示例
相關(guān)文章
一文搞懂MyBatis多數(shù)據(jù)源Starter實(shí)現(xiàn)
本文將實(shí)現(xiàn)一個(gè)MyBatis的Springboot的Starter包,引用這個(gè)Starter包后,僅需要提供少量配置信息,就能夠完成MyBatis多數(shù)據(jù)源的初始化和使用,需要的小伙伴可以參考一下2023-04-04
SpringMVC詳解如何映射請(qǐng)求數(shù)據(jù)
這篇文章主要給大家介紹了關(guān)于SpringMvc映射請(qǐng)求數(shù)據(jù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-06-06
SpringBoot處理JSON數(shù)據(jù)方法詳解
這篇文章主要介紹了SpringBoot整合Web開(kāi)發(fā)中Json數(shù)據(jù)處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-10-10
通過(guò)第三方接口發(fā)送短信驗(yàn)證碼/短信通知(推薦)
這篇文章主要介紹了通過(guò)第三方接口發(fā)送短信驗(yàn)證碼/短信通知(推薦)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08
基于Spring?Boot的線程池監(jiān)控問(wèn)題及解決方案
這篇文章主要介紹了基于Spring?Boot的線程池監(jiān)控方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
Java定時(shí)器Timer與TimerTask的使用詳解
這篇文章主要介紹了Java定時(shí)器Timer與TimerTask的使用詳解,在JDK類庫(kù)中Timer主要負(fù)責(zé)計(jì)劃任務(wù)的功能,也就是在指定時(shí)間執(zhí)行某一任務(wù),執(zhí)行時(shí)候會(huì)在主線程之外起一個(gè)單獨(dú)的線程執(zhí)行指定的任務(wù),該類主要是設(shè)置任務(wù)計(jì)劃,但封裝的類是TimerTask類,需要的朋友可以參考下2023-10-10
Java鏈表元素查找實(shí)現(xiàn)原理實(shí)例解析
這篇文章主要介紹了Java鏈表元素查找實(shí)現(xiàn)原理實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07

