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ā)來的文件 @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項目啟動后,打開這個index.html的頁面要輸入:localhost:8080/index.html
接下來通過斷點調(diào)試獲取查看前端發(fā)送過來的文件
文件的”到此一游“:該文件所在的路徑的文件夾是個臨時文件夾,運行完畢后這個文件夾里的內(nèi)容清空
前端上傳文件本地存儲
@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(); }
文件上傳還存在一個要考慮的問題:如果兩次提交的是不一樣的文件,但是文件名稱一樣,那么第二次提交的圖片會把第一次提交的文件給替換(覆蓋)因此可以使用UUID命名來解決。
生成UUID
import java.util.UUID; public class UUIDExample { public static void main(String[] args) { // 生成一個隨機UUID UUID uuid = UUID.randomUUID(); // 輸出UUID System.out.println("生成的UUID: " + uuid.toString()); } }
使用UUID解決以上問題
@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(); // 獲取文件擴展名,從最后一個點后開始截取 String extension = originalFilename.substring(originalFilename.lastIndexOf(".")); // 生成新的文件名,使用UUID并加上文件擴展名 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));
這個代碼的路徑最后一定要寫個“/”,使得文件保存在那個文件夾下。
上傳文件大小限制
默認上傳文件的最大大小為1MB,超過該大小需要在配置文件配置
servlet: multipart: # 最大單個文件大小 max-file-size: 10MB # 最大請求大?。òㄋ形募捅韱螖?shù)據(jù)) max-request-size: 100MB
阿里云OSS
阿里云對象存儲oss(object Storage Service),是一款海量、安全、低成本、高可靠的云存儲服務。使用oss
您可以通過網(wǎng)絡(luò)隨時存儲和調(diào)用包括文本、圖片、音頻和視頻等在內(nèi)的各種文件。
具體怎么配看:視頻
配置好相關(guān)密鑰等配置后,創(chuàng)建bucket。接下來可以通過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ǔ)配置:連接服務并驗證個人身份 */ // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。 String endpoint = "https://oss-cn-shenzhen.aliyuncs.com"; // 從環(huán)境變量中獲取訪問憑證。運行本代碼示例之前,請確保已設(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。 // 如果未指定本地路徑,則默認從示例程序所屬項目對應本地路徑中上傳文件。 String filePath= "D:\\Mycode\\webcode\\imag\\nu.webp"; // 創(chuàng)建OSSClient實例。 OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { // 創(chuàng)建PutObjectRequest對象。 PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath)); // 如果需要上傳時設(shè)置存儲類型和訪問權(quán)限,請參考以下示例代碼。 // 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的服務地址,這里是深圳區(qū)域的地址 private String endpoint = "https://oss-cn-shenzhen.aliyuncs.com"; // 指定要上傳到的存儲桶名稱 private String bucketName = "lwq-buckets"; // 指定阿里云的區(qū)域,這里是深圳區(qū)域 private String region = "cn-shenzhen"; /** * 上傳文件到阿里云OSS * @param content 文件的字節(jié)數(shù)組內(nèi)容 * @param originalFilename 原始文件名,用于生成新的文件名 * @return 上傳后文件的訪問路徑 * @throws Exception 可能拋出的異常 */ public String upload(byte[] content, String originalFilename) throws Exception { // 從環(huán)境變量中獲取訪問密鑰,確保在運行代碼前設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 獲取object對象路徑,例如2024/06/21.png。Object類型中不能包含Bucket名稱 String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM")); // 生成一個新的文件名,使用UUID確保唯一性,并保留原始文件的擴展名 String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = dir + "/" + newFileName; // 生成完整的對象名稱 // 創(chuàng)建OSSClient實例 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // 設(shè)置簽名版本為V4 // 使用OSSClientBuilder創(chuàng)建OSS客戶端實例,配置包括端點、憑證提供者、客戶端配置和區(qū)域 OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { // 上傳文件內(nèi)容到指定的存儲桶和對象路徑 ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); } finally { // 確保無論上傳是否成功,都會關(guān)閉OSS客戶端 ossClient.shutdown(); } // 生成并返回文件的完整訪問路徑 return endpoint.split("http://")[0] + "http://" + bucketName + "." + endpoint.split("http://")[1] + "/" + objectName; } }
使用該類
@Autowired // 自動注入AliyunOSSOperator實例 private AliyunOSSOperator aliyunOSSOperator; @PostMapping("/upload") // 定義一個POST請求處理方法,映射到/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é)果,包含文件的訪問URL return Result.success(url); }
這樣上傳到阿里云的文件以年月劃分了文件夾
參數(shù)配置進一步優(yōu)化
指將一些需要靈活變化的參數(shù),配置在配置文件中,然后通過 @Value 注解來注入外部配置的屬性。
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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot如何實現(xiàn)調(diào)用controller和Service層方法
- springboot中的controller參數(shù)映射問題小結(jié)
- springboot如何通過controller層實現(xiàn)頁面切換
- springboot Controller直接返回String類型帶來的亂碼問題及解決
- SpringBoot之controller參數(shù)校驗詳解
- springboot中@RestController注解實現(xiàn)
- SpringBoot通過注解監(jiān)測Controller接口的代碼示例
- springboot controller參數(shù)注入方式
- SpringBoot中@RestControllerAdvice @ExceptionHandler異常統(tǒng)一處理類失效原因分析
- SpringBoot和MybatisPlus實現(xiàn)通用Controller示例
相關(guān)文章
JVM堆內(nèi)存溢出后,其他線程是否可繼續(xù)工作的問題解析
這篇文章主要介紹了JVM 堆內(nèi)存溢出后,其他線程是否可繼續(xù)工作?,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-08-08如何解決Spring in action @valid驗證不生效的問題
這篇文章主要介紹了如何解決Spring in action @valid驗證不生效的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06Java中抽象類和接口的區(qū)別_動力節(jié)點Java學院整理
java抽象類和接口最本質(zhì)的區(qū)別是接口里不能實現(xiàn)方法--接口中的方法全是抽象方法。抽象類中可實現(xiàn)方法--抽象類中的方法可以不是抽象方法,下文給大家簡單介紹下,需要的的朋友參考下2017-04-04MPAndroidChart開源圖表庫的使用介紹之餅狀圖、折線圖和柱狀圖
這篇文章主要介紹了MPAndroidChart開源圖表庫的使用介紹之餅狀圖、折線圖和柱狀圖的相關(guān)資料,需要的朋友可以參考下2016-02-02