Java實(shí)現(xiàn)文件上傳和下載的方法詳解
1、文件上傳
1.1 介紹
文件上傳,也稱為upload,是指將本地圖片、視頻、音頻等文件上傳到服務(wù)器上,可以供其他用戶瀏覽或下載的過程。文件上傳在項(xiàng)目中應(yīng)用非常廣泛,我們經(jīng)常發(fā)微博、發(fā)微信朋友圈都用到了文件上傳功能。
文件上傳時(shí),對(duì)頁面的form表單有如下要求:
表單屬性 | 取值 | 說明 |
---|---|---|
method | post | 必須選擇post方式提交 |
enctype | multipart/form-data | 采用multipart格式上傳文件 |
type | file | 使用input的file控件上傳 |
舉例:
<form method="post" action="/common/upload" enctype="multipart/form-data"> <input name="myFile" type="file" /> <input type="submit" value="提交" /> </form>
目前一些前端組件庫也提供了相應(yīng)的上傳組件,例如Element-ui,但是底層原理還是基于form表單的文件上傳。
1.2 代碼實(shí)現(xiàn)
這里我主要實(shí)現(xiàn)后端代碼,對(duì)于前端頁面,可以使用ElementUI提供的上傳組件。
1、application.yml
首先我們需要在yml 文件里 配置一下文件存儲(chǔ)路徑。
2、Controller
然后我們就可以編寫上傳文件的Controller。
編寫文件上傳的方法, 通過MultipartFile類型的參數(shù)即可接收上傳的文件, 方法形參的名稱需要與頁面的file域的name屬性一致。
package com.jie.reggjie.controller; import com.jie.reggjie.common.R; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; /** * 文件上傳和下載 */ @RestController @RequestMapping("/common") @Slf4j public class CommonController { @Value("${reggie.path}") private String basePath; /** * 文件上傳 * * @param file * @return */ @PostMapping("/upload") public R<String> upload(MultipartFile file) { return null; } }
實(shí)現(xiàn)步驟:
1、獲取文件的原始文件名, 通過原始文件名獲取文件后綴。
2、我們可以通過UUID重新聲明文件名, 避免文件名稱重復(fù)造成文件覆蓋。
3、創(chuàng)建文件存放目錄,防止目錄不存在導(dǎo)致文件上傳失敗。
4、將上傳的臨時(shí)文件轉(zhuǎn)存到指定位置。
注:
因?yàn)槲覀凕c(diǎn)擊上傳其實(shí)是將文件臨時(shí)保存到我們計(jì)算機(jī)的一個(gè)臨時(shí)文件夾內(nèi),如果我們不將其轉(zhuǎn)存,本次請(qǐng)求結(jié)束后,文件也會(huì)自動(dòng)刪除。
最后將文件名返回,我這里需要將文件名存到數(shù)據(jù)庫內(nèi)。
完整代碼:
/** * @description: 文件上傳 * @author: Jie * @date: 2022/8/15 10:16 * @param: [file] 文件 * @return: 文件名 **/ @PostMapping("/upload") public R<String> upload(MultipartFile file) { // 1、獲取文件的原始文件名, 通過原始文件名獲取文件后綴 例如:abc.jpg String originalFilename = file.getOriginalFilename(); String suffix = originalFilename.substring(originalFilename.lastIndexOf(".")); // 2、使用UUID重新生成文件名,防止文件名稱重復(fù)造成文件覆蓋 String fileName = UUID.randomUUID().toString() + suffix; // 3、創(chuàng)建一個(gè)目錄對(duì)象 File dir = new File(basePath); //判斷當(dāng)前目錄是否存在 if (!dir.exists()) { //目錄不存在,需要?jiǎng)?chuàng)建 dir.mkdirs(); } try { // 4、將臨時(shí)文件轉(zhuǎn)存到指定位置 file.transferTo(new File(basePath + fileName)); } catch (IOException e) { e.printStackTrace(); } return R.success(fileName); }
2、下載
2.1 介紹
文件下載,也稱為download,是指將文件從服務(wù)器傳輸?shù)奖镜赜?jì)算機(jī)的過程。
通過瀏覽器進(jìn)行文件下載,通常有兩種表現(xiàn)形式:
1、 以附件形式下載,彈出保存對(duì)話框,將文件保存到指定磁盤目錄
2、直接在瀏覽器中打開
而我要實(shí)現(xiàn)的就是在瀏覽器中直接打開。
文件下載,前端頁面可以使用<img>標(biāo)簽展示下載的圖片。
<img v-if="imageUrl" :src="imageUrl" class="avatar"></img>
那么,通過<img>標(biāo)簽如何展示圖片數(shù)據(jù)呢,我們來看一下具體的流程:
在文件上傳成功后,在 handleAvatarSuccess 方法中獲取文件上傳成功之后返回的數(shù)據(jù)(文件名),然后調(diào)用 /common/download?name=xxx 進(jìn)行文件的下載。
在這里,我們想讓上傳的照片能夠在頁面展示出來,所以我們就需要在服務(wù)端將文件以流的形式寫回瀏覽器。
2.2 代碼實(shí)現(xiàn)
在 Controller 中定義方法download,并接收頁面?zhèn)鬟f的參數(shù)name,然后讀取圖片文件的數(shù)據(jù),然后以流的形式寫回瀏覽器。
/** * @description: 文件下載 * @author: Jie * @date: 2022/8/15 10:46 **/ @GetMapping("/download") public void download(String name, HttpServletResponse response){ }
實(shí)現(xiàn)步驟:
1、定義輸入流,通過輸入流讀取文件內(nèi)容。
2、通過response對(duì)象,獲取到輸出流。
3、通過response對(duì)象設(shè)置響應(yīng)數(shù)據(jù)格式(image/jpeg)。
4、 通過輸入流讀取文件數(shù)據(jù),然后通過上述的輸出流寫回瀏覽器。
5、 關(guān)閉資源
完整代碼:
/** * @description: 文件下載 * @author: Jie * @date: 2022/8/15 10:46 **/ @GetMapping("/download") public void download(String name, HttpServletResponse response){ try { // 1、定義輸入流,通過輸入流讀取文件內(nèi)容 FileInputStream fileInputStream = new FileInputStream(new File(basePath + name)); // 2、通過response對(duì)象,獲取到輸出流 ServletOutputStream outputStream = response.getOutputStream(); // 3、通過response對(duì)象設(shè)置響應(yīng)數(shù)據(jù)格式(image/jpeg) response.setContentType("image/jpeg"); int len = 0; byte[] bytes = new byte[1024]; while ((len = fileInputStream.read(bytes)) != -1){ // 4、通過輸入流讀取文件數(shù)據(jù),然后通過上述的輸出流寫回瀏覽器 outputStream.write(bytes,0,len); // 刷新 outputStream.flush(); } // 5、關(guān)閉資源 outputStream.close(); fileInputStream.close(); } catch (Exception e) { e.printStackTrace(); } }
到此這篇關(guān)于Java實(shí)現(xiàn)文件上傳和下載的方法詳解的文章就介紹到這了,更多相關(guān)Java文件上傳下載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java后臺(tái)實(shí)現(xiàn)瀏覽器一鍵導(dǎo)出下載zip壓縮包
這篇文章主要為大家詳細(xì)介紹了Java后臺(tái)實(shí)現(xiàn)瀏覽器一鍵導(dǎo)出下載zip壓縮包,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Android?Java判斷密碼強(qiáng)度方法實(shí)例(強(qiáng)度顯示)
在現(xiàn)代社會(huì)中,密碼是確保我們個(gè)人信息和賬戶安全的重要手段之一,為了提高密碼的安全性,我們可以使用正則表達(dá)式來判斷密碼的強(qiáng)度,這篇文章主要給大家介紹了關(guān)于Android?Java判斷密碼強(qiáng)度(強(qiáng)度顯示)的相關(guān)資料,需要的朋友可以參考下2024-03-03Spring中的ApplicationContext與BeanFactory詳解
這篇文章主要介紹了Spring中的ApplicationContext與BeanFactory詳解,Spring的IoC容器就是一個(gè)實(shí)現(xiàn)了BeanFactory接口的可實(shí)例化類,事實(shí)上, Spring提供了兩種不同的容器,一種是最基本的BeanFactory,另一種是擴(kuò)展的ApplicationContext,需要的朋友可以參考下2024-01-01mybatis框架order by作為參數(shù)傳入時(shí)失效的解決
這篇文章主要介紹了mybatis框架order by作為參數(shù)傳入時(shí)失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06IntelliJ IDEA 2019.2 x64的安裝、應(yīng)用與簡單配置(圖文)
這篇文章主要介紹了IntelliJ IDEA 2019.2 x64的安裝、應(yīng)用與簡單配置,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10Springboot 使用 maven-resources-plugin 打包變量替換ja
這篇文章主要介紹了Springboot 使用 maven-resources-plugin 打包變量替換jar沒有打包進(jìn)去、Jar包沒有被使用的解決方法,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-08-08