Java實(shí)現(xiàn)文件上傳和下載的方法詳解
1、文件上傳
1.1 介紹
文件上傳,也稱為upload,是指將本地圖片、視頻、音頻等文件上傳到服務(wù)器上,可以供其他用戶瀏覽或下載的過程。文件上傳在項(xiàng)目中應(yīng)用非常廣泛,我們經(jīng)常發(fā)微博、發(fā)微信朋友圈都用到了文件上傳功能。
文件上傳時(shí),對(duì)頁(yè)面的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>
目前一些前端組件庫(kù)也提供了相應(yīng)的上傳組件,例如Element-ui,但是底層原理還是基于form表單的文件上傳。

1.2 代碼實(shí)現(xiàn)
這里我主要實(shí)現(xiàn)后端代碼,對(duì)于前端頁(yè)面,可以使用ElementUI提供的上傳組件。
1、application.yml
首先我們需要在yml 文件里 配置一下文件存儲(chǔ)路徑。

2、Controller
然后我們就可以編寫上傳文件的Controller。
編寫文件上傳的方法, 通過MultipartFile類型的參數(shù)即可接收上傳的文件, 方法形參的名稱需要與頁(yè)面的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ù)庫(kù)內(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)的就是在瀏覽器中直接打開。

文件下載,前端頁(yè)面可以使用<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)行文件的下載。
在這里,我們想讓上傳的照片能夠在頁(yè)面展示出來,所以我們就需要在服務(wù)端將文件以流的形式寫回瀏覽器。
2.2 代碼實(shí)現(xiàn)
在 Controller 中定義方法download,并接收頁(yè)面?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)文章
Bloc事件流是一個(gè)阻塞隊(duì)列結(jié)論解析
這篇文章主要為大家介紹了Bloc事件流是一個(gè)阻塞隊(duì)列結(jié)論解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
Java實(shí)現(xiàn)Word/Pdf/TXT轉(zhuǎn)html的實(shí)例代碼
本文主要介紹了Java實(shí)現(xiàn)Word/Pdf/TXT轉(zhuǎn)html的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
Java 內(nèi)置Http Server構(gòu)建web應(yīng)用案例詳解
這篇文章主要介紹了Java 內(nèi)置Http Server構(gòu)建web應(yīng)用案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09
SpringBoot中的ImportSelector類動(dòng)態(tài)加載bean詳解
這篇文章主要介紹了SpringBoot中的ImportSelector類動(dòng)態(tài)加載bean詳解,ImportSelector接口是spring中導(dǎo)入外部配置的核心接口,根據(jù)給定的條件(通常是一個(gè)或多個(gè)注釋屬性)判定要導(dǎo)入那個(gè)配置類,在spring自動(dòng)化配置和@EnableXXX中都有它的存在,需要的朋友可以參考下2024-01-01
MybatisPlus實(shí)現(xiàn)insertBatchSomeColumn進(jìn)行批量增加
本文主要介紹了MybatisPlus實(shí)現(xiàn)insertBatchSomeColumn進(jìn)行批量增加,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
JAVA實(shí)現(xiàn)社會(huì)統(tǒng)一信用代碼校驗(yàn)的方法
這篇文章主要介紹了JAVA實(shí)現(xiàn)社會(huì)統(tǒng)一信用代碼校驗(yàn)的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07

