如何基于SpringWeb?MultipartFile實(shí)現(xiàn)文件上傳、下載功能
前言
在Web開發(fā)中,文件上傳是一個(gè)常見的功能需求。Spring框架提供了MultipartFile接口,用于處理文件上傳請(qǐng)求。MultipartFile可以代表一個(gè)多部分文件上傳請(qǐng)求中的一個(gè)文件,提供了一系列方法用于獲取文件的各種屬性和內(nèi)容,使得在后端處理文件上傳變得十分方便。下面我們將介紹MultipartFile在Web應(yīng)用中的幾種常見使用場(chǎng)景。
1. 圖片上傳
在Web應(yīng)用中,圖片上傳是一種常見的場(chǎng)景。用戶需要上傳頭像、相片、證件照等圖片文件,而后端需要接收并保存這些文件。使用MultipartFile接口可以輕松地實(shí)現(xiàn)圖片文件的接收和處理。通過獲取文件的原始文件名、內(nèi)容類型、大小等屬性,我們可以實(shí)現(xiàn)對(duì)圖片文件的有效管理和存儲(chǔ)。例如,我們可以將圖片文件保存到服務(wù)器的文件系統(tǒng)中,或者將其存儲(chǔ)到云存儲(chǔ)服務(wù)中。
2. 文件下載
除了文件上傳,文件下載也是Web應(yīng)用中常見的功能需求。使用MultipartFile接口,我們可以實(shí)現(xiàn)文件的下載功能。在服務(wù)器端,我們可以將文件作為MultipartFile對(duì)象進(jìn)行處理,并通過設(shè)置響應(yīng)頭信息,將文件作為下載內(nèi)容返回給客戶端??蛻舳私邮盏轿募螅梢詫⑵浔4娴奖镜卮疟P或進(jìn)行其他處理。
3. 文件編輯
在Web應(yīng)用中,有時(shí)候用戶需要對(duì)上傳的文件進(jìn)行編輯操作,例如修改文件名、修改文件內(nèi)容等。使用MultipartFile接口,我們可以實(shí)現(xiàn)對(duì)文件的編輯功能。首先,我們可以通過MultipartFile接口獲取上傳的文件對(duì)象,然后對(duì)其進(jìn)行相應(yīng)的編輯操作。例如,我們可以修改文件的名稱、修改文件的內(nèi)容等。編輯完成后,我們可以將修改后的文件保存到服務(wù)器或返回給客戶端。
4. 文件預(yù)覽和展示
在Web應(yīng)用中,有時(shí)候我們需要將上傳的文件進(jìn)行預(yù)覽或展示。例如,在文檔管理系統(tǒng)中,用戶需要預(yù)覽或下載文檔文件。使用MultipartFile接口,我們可以實(shí)現(xiàn)文件的預(yù)覽和展示功能。我們可以將文件作為MultipartFile對(duì)象進(jìn)行處理,然后將其內(nèi)容轉(zhuǎn)換為適當(dāng)?shù)母袷竭M(jìn)行展示。例如,對(duì)于PDF文件,我們可以使用PDF閱讀器插件進(jìn)行展示;對(duì)于圖片文件,我們可以將其直接展示在網(wǎng)頁(yè)上。
5. 文件批量上傳和處理
在實(shí)際應(yīng)用中,有時(shí)候用戶需要批量上傳多個(gè)文件,并對(duì)這些文件進(jìn)行處理。使用MultipartFile接口,我們可以實(shí)現(xiàn)文件的批量上傳和處理功能。我們可以將多個(gè)文件作為一個(gè)多部分文件上傳請(qǐng)求進(jìn)行處理,然后對(duì)每個(gè)文件進(jìn)行相應(yīng)的操作。例如,我們可以將多個(gè)圖片文件批量上傳到服務(wù)器,并對(duì)它們進(jìn)行壓縮、裁剪等處理。
代碼
package com.javagpt.back.controller; import com.javagpt.application.context.UserAppContextHolder; import com.javagpt.application.file.FileApplicationService; import com.javagpt.application.file.FileDTO; import com.javagpt.common.annotation.RespSuccess; import com.javagpt.common.constant.EMConstant; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; @Api(tags = "文件接口") @Slf4j @RestController @RequestMapping(EMConstant.API_V1 + "/file") @RespSuccess @RequiredArgsConstructor public class FileController { private final FileApplicationService fileApplicationService; @ApiOperation("通用文件上傳") @PostMapping(value = "/uploadFile") public FileDTO uploadFile(@RequestParam("file") MultipartFile multipartFile) throws IOException { Long enterpriseId = UserAppContextHolder.getCurrentUser().getEnterpriseId(); FileDTO fileDTO = fileApplicationService.saveFile(enterpriseId, multipartFile); return fileDTO; } //@PreAuthorize("hasAuthority('mp:file:download')") @ApiOperation("下載文件") @GetMapping(value = "/downloadFile") public void download(@RequestParam(value = "id") Long id, HttpServletResponse response) throws IOException { fileApplicationService.downloadFile(response, id, UserAppContextHolder.getCurrentUser().getEnterpriseId()); } @ApiOperation("查看文件信息") @GetMapping(value = "/info") public FileDTO fileInfo(@RequestParam(value = "id") Long id) throws IOException { return fileApplicationService.findById(id); } @ApiOperation("下載視頻") @GetMapping(value = "/downloadFile2") public void download2(@RequestParam(value = "id") Long id, HttpServletRequest request, HttpServletResponse response) throws IOException { fileApplicationService.downloadVideo(request, response, id, UserAppContextHolder.getCurrentUser().getEnterpriseId()); } }
package com.javagpt.application.file; import com.javagpt.common.exception.BusinessRuntimeException; import com.javagpt.common.oos.OssService; import com.javagpt.common.util.ModelUtils; import com.javagpt.common.util.SpringResponseUtils; import com.javagpt.file.entity.FileEntity; import com.javagpt.file.repository.FileRepository; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.io.*; @Service @Slf4j @RequiredArgsConstructor public class FileApplicationService { private final OssService ossService; private final FileRepository fileRepository; public FileDTO findById(Long id) { FileEntity fileEntity = fileRepository.findById(id); return ModelUtils.convert(fileEntity, FileDTO.class); } @Transactional public FileDTO saveFile(Long enterpriseId, MultipartFile file) { FileEntity fileEntity = saveFile(enterpriseId, file, null); return ModelUtils.convert(fileEntity, FileDTO.class); } @Transactional public FileEntity saveFile(Long enterpriseId, MultipartFile file, String fileName) { String originalFilename = file.getOriginalFilename(); String name = StringUtils.isBlank(fileName) ? FilenameUtils.getBaseName(originalFilename) : fileName; String suffix = FilenameUtils.getExtension(originalFilename); long size = file.getSize(); FileEntity fileEntity = new FileEntity(); fileEntity.setName(name).setSuffix(suffix).setSize(size).setEnterpriseId(enterpriseId); fileEntity = fileEntity.save(); String key = fileEntity.getPath(); InputStream inputStream = null; try { inputStream = file.getInputStream(); } catch (IOException e) { log.error("saveFile error:", e); throw BusinessRuntimeException.error("上傳文件失敗"); } ossService.uploadFile(inputStream, key); IOUtils.closeQuietly(inputStream); return fileEntity; } @Transactional public FileEntity saveFile(File file) { long size = file.length(); FileEntity fileEntity = new FileEntity(); String baseName = FilenameUtils.getBaseName(file.getName()); String extension = FilenameUtils.getExtension(file.getName()); fileEntity.setName(baseName).setSuffix(extension).setSize(size); fileEntity = fileEntity.save(); String key = fileEntity.getPath(); FileInputStream inputStream = null; try { inputStream = new FileInputStream(file); ossService.uploadFile(inputStream, key); } catch (FileNotFoundException e) { log.error("saveFile error:", e); throw BusinessRuntimeException.error("上傳文件失敗"); } IOUtils.closeQuietly(inputStream); return fileEntity; } public void downloadFile(HttpServletResponse response, Long fileId, Long enterpriseId) throws IOException { FileEntity fileEntity = fileRepository.findById(fileId); if (fileEntity == null) { throw BusinessRuntimeException.error("無(wú)效的文件Id"); } String key = fileEntity.getPath(); InputStream inputStream = ossService.downloadFile(key); SpringResponseUtils.writeAndFlushResponse(inputStream, response, fileEntity.fileFullName()); } public void downloadVideo(HttpServletRequest request, HttpServletResponse response, Long fileId, Long enterpriseId) throws IOException { FileEntity fileEntity = fileRepository.findById(fileId); if (fileEntity == null) { throw BusinessRuntimeException.error("無(wú)效的文件Id"); } response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes"); Long fileSize = fileEntity.getSize(); long start = 0, end = fileSize - 1; //判斷前端需不需要分片下載 if (StringUtils.isNotBlank(request.getHeader("Range"))) { response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT); String numRange = request.getHeader("Range").replaceAll("bytes=", ""); String[] strRange = numRange.split("-"); if (strRange.length == 2) { start = Long.parseLong(strRange[0].trim()); end = Long.parseLong(strRange[1].trim()); //若結(jié)束字節(jié)超出文件大小 取文件大小 if (end > fileSize - 1) { end = fileSize - 1; } } else { //若只給一個(gè)長(zhǎng)度 開始位置一直到結(jié)束 start = Long.parseLong(numRange.replaceAll("-", "").trim()); } } long rangeLength = end - start + 1; String contentRange = new StringBuffer("bytes ").append(start).append("-").append(end).append("/").append(fileSize).toString(); response.setHeader(HttpHeaders.CONTENT_RANGE, contentRange); response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(rangeLength)); String key = fileEntity.getPath(); InputStream inputStream = ossService.downloadFile2(key, start, end); SpringResponseUtils.writeAndFlushResponse(inputStream, response, fileEntity.fileFullName()); } }
總之,MultipartFile接口在Web應(yīng)用中具有廣泛的應(yīng)用場(chǎng)景,可以實(shí)現(xiàn)文件上傳、下載、編輯、預(yù)覽和批量處理等功能。通過熟練掌握MultipartFile接口的使用方法和技巧,我們可以更加高效地處理文件上傳和下載請(qǐng)求,提升Web應(yīng)用的用戶體驗(yàn)和功能性能。
總結(jié)
到此這篇關(guān)于如何基于SpringWeb MultipartFile實(shí)現(xiàn)文件上傳、下載功能的文章就介紹到這了,更多相關(guān)SpringWeb MultipartFile文件上傳下載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解SpringMVC?HandlerInterceptor攔截器的使用與參數(shù)
本文主要介紹了詳解SpringMVC?HandlerInterceptor攔截器的使用與參數(shù),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01ZooKeeper入門教程三分布式鎖實(shí)現(xiàn)及完整運(yùn)行源碼
本文是ZooKeeper入門系列教程,分布式鎖有多種實(shí)現(xiàn)方式,比如通過數(shù)據(jù)庫(kù)、redis都可實(shí)現(xiàn)。作為分布式協(xié)同工具ZooKeeper,當(dāng)然也有著標(biāo)準(zhǔn)的實(shí)現(xiàn)方式。本文介紹在zookeeper中如何實(shí)現(xiàn)排他鎖2022-01-01如何在SpringBoot項(xiàng)目里進(jìn)行統(tǒng)一異常處理
這篇文章主要介紹了如何在SpringBoot項(xiàng)目里進(jìn)行統(tǒng)一異常處理,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值。需要的小伙伴可以參考一下2022-07-07mybatis-plus配置日志兩種實(shí)現(xiàn)方式
這篇文章主要給大家介紹了關(guān)于mybatis-plus配置日志兩種實(shí)現(xiàn)方式的相關(guān)資料,Mybatis-plus集成了日志框架,可以將程序運(yùn)行時(shí)產(chǎn)生的日志進(jìn)行記錄,方便開發(fā)人員進(jìn)行問題排查,需要的朋友可以參考下2023-09-09SpringBoot3整合pageHelper實(shí)現(xiàn)分頁(yè)功能
PageHelper是一個(gè)開源的Java分頁(yè)插件,它提供了方便的分頁(yè)查詢功能,適用于大多數(shù)基于Java的持久層框架(如MyBatis、Hibernate等),本文給大家介紹了springboot3整合pageHelper實(shí)現(xiàn)分頁(yè)功能的方法,需要的朋友可以參考下2024-08-08SpringBoot獲取application.properties文件中文亂碼問題及解決
這篇文章主要介紹了SpringBoot獲取application.properties文件中文亂碼問題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05

Spring Boot不同版本Redis設(shè)置JedisConnectionFactory詳解

Spring Data JPA結(jié)合Mybatis進(jìn)行分頁(yè)查詢的實(shí)現(xiàn)