java文件/圖片的上傳與下載以及MultipartFile詳解
一、概述
MultipartFile為org.springframework.web.mutipart包下的一個(gè)類,也就是說如果想使用MultipartFile這個(gè)類就必須引入spring框架,換句話說,如果想在項(xiàng)目中使用MultipartFile這個(gè)類,那么項(xiàng)目必須要使用spring框架才可以,否則無法引入這個(gè)類。
MultipartFile翻譯成中文來講就是“多組件的文檔”,不用太在乎他的中文含義,一般來講使用MultipartFile這個(gè)類主要是來實(shí)現(xiàn)以表單的形式進(jìn)行文件上傳功能。
二、MultipartFile中的方法
getName方法
getName方法獲取的是前后端約定的傳入文件的參數(shù)的名稱
getOriginalFileName方法
getOriginalFileName方法獲取的是文件的完整名稱,包括文件名稱+文件拓展名。
getContentType方法
getContentType方法獲取的是文件的類型,注意是文件的類型,不是文件的拓展名。
isEmpty方法
isEmpty方法用來判斷傳入的文件是否為空,如果為空則表示沒有傳入任何文件。
getSize方法
getSize方法用來獲取文件的大小,單位是字節(jié)。
getBytes方法
getBytes方法用來將文件轉(zhuǎn)換成一種字節(jié)數(shù)組的方式進(jìn)行傳輸,會(huì)拋出IOException異常。
getInputStream方法
getInputStream方法用來將文件轉(zhuǎn)換成輸入流的形式來傳輸文件,會(huì)拋出IOException異常。
transferTo方法
transferTo方法用來將接收文件傳輸?shù)浇o定目標(biāo)路徑
三、MultipartFile的一些使用技巧
- (1)我們在使用MultipartFile作為參數(shù)傳遞的時(shí)候,可以將MultipartFile聲明為一個(gè)數(shù)組,這樣就能支持多文件傳輸,如果只需要傳輸一個(gè)文件,則去掉數(shù)組就好了。
- (2)可以根據(jù)MultipartFile的getSize方法來獲取到傳輸文件的大小,這樣就能限定傳輸過來的文件的大小了。
四、上傳代碼顯示
- 業(yè)務(wù)邏輯代碼:
package cn.xcy.demo.controller;
import cn.hutool.core.io.FileUtil;
import cn.xcy.demo.FlieUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
@Slf4j
@RestController
@RequestMapping("/file")
public class FileUploadController {
/**
* 上傳文件
* 1、判斷文件是否為空
* 2、獲取文件名、文件類型、文件大小(可以限定文件類型、以及文件大小)
* 3、設(shè)置文件上傳路徑
* 4、以流的方式將文件輸出
* 5、返回上傳成功
* @param file
* @return
* @throws Exception
*/
@PostMapping("/upload")
public String uploadImage(@RequestParam("file") MultipartFile file) throws Exception{
// 判斷文件是否為空
if (file.isEmpty()) {
return "上傳失敗";
}
//文件類型為
String contentType = file.getContentType();
log.info("文件類型為:" + contentType);
if (contentType.equals("image/jpeg")){
return "請上傳正確格式的文件";
}
// 獲取原始文件名
String fileName = file.getOriginalFilename();
log.info("上傳的文件名為:" + fileName);
try {
// 將文件保存到指定位置
byte[] bytes = file.getBytes();
log.info("文件大小為:" + bytes.length);
// TODO: 根據(jù)業(yè)務(wù)需求選擇合適的存儲(chǔ)方式,比如保存到本地磁盤或云存儲(chǔ)
// 獲取生成后的文件名
String s = FlieUtils.generateRandomFileName(fileName);
// 將文件保存到指定位置
FlieUtils.upload(file,"C:\\Users\\liguoming\\Desktop",s);
return "上傳成功";
} catch (Exception e) {
e.printStackTrace();
return "上傳失敗";
}
}
}- FlieUtils工具類:
package cn.xcy.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.UUID;
@Slf4j
public class FlieUtils {
/**
* @param file 文件
* @param fileName 新的隨機(jī)文件名
*/
public static void upload(MultipartFile file, String destPath, String fileName) {
File dest = new File(destPath + File.separator + fileName);
//判斷文件父目錄是否存在
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
//保存文件
file.transferTo(dest);
} catch (Exception e) {
log.info("Save file exception. {}", e.getMessage());
}
}
/**
* 輸出文件的后綴名
* @param fileName
* @return
*/
public static String getSuffix(String fileName) {
// fileName.substring(fileName.lastIndexOf("."))
// 是C#中的字符串操作,它的作用是從文件名字符串中截取最后一個(gè)點(diǎn)(.)及其后面的所有字符。這個(gè)操作可以用來獲取文件的擴(kuò)展名。
return fileName.substring(fileName.lastIndexOf("."));
}
/**
* 輸出文件的新名稱 (名字+后綴名)
* @param fileName
* @return
*/
public static String generateRandomFileName(String fileName) {
return UUID.randomUUID() + getSuffix(fileName);
}
/**
* @param name
* @Description 設(shè)置響應(yīng)頭部信息
* @Throws
* @Return java.lang.String
* @Date 2023-08-02 13:39:15
* @Author lgm
*/
public static String fileContentType(String name) {
String result = "";
String fileType = name.toLowerCase();
if (fileType.endsWith(".png")) {
result = "image/png";
} else if (fileType.endsWith(".gif")) {
result = "image/gif";
} else if (fileType.endsWith(".jpg") || fileType.endsWith(".jpeg")) {
result = "image/jpeg";
} else if (fileType.endsWith(".svg")) {
result = "image/svg+xml";
} else if (fileType.endsWith(".doc")) {
result = "application/msword";
} else if (fileType.endsWith(".xls")) {
result = "application/x-excel";
} else if (fileType.endsWith(".zip")) {
result = "application/zip";
} else if (fileType.endsWith(".pdf")) {
result = "application/pdf";
} else if (fileType.endsWith(".mpeg")) { //MP3
result = "audio/mpeg";
} else if (fileType.endsWith(".mp4")) {
result = "video/mp4";
} else if (fileType.endsWith(".plain")) {
result = "text/plain";
} else if (fileType.endsWith(".html")) {
result = "text/html";
} else if (fileType.endsWith(".json")) {
result = "application/json";
} else{
result = "application/octet-stream";
}
return result;
}
}五、下載的代碼顯示
- 業(yè)務(wù)邏輯代碼:
/**
* 下載文件
* 1、需要傳入文件名稱
* 2、先將文件的存放路徑+名稱獲取到
* 3、設(shè)置響應(yīng)頭,告訴瀏覽器需要下載文件夾
* 4、設(shè)置響應(yīng)體,將文件讀取出來,寫入到響應(yīng)體中
* 5、response.getOutputStream() 輸出字節(jié)流, 客戶端會(huì)下載字節(jié)流并生成文件保存本地
* @param filename
* @param response
* @return
* @throws IOException
*/
@RequestMapping("/fileload")
public String fileload(@RequestParam("filename")String filename, HttpServletResponse response) throws IOException {
// 文件的存放位置
String filePath = "C:\\Users\\liguoming\\Desktop\\" + filename;
File file = new File(filePath);
// 設(shè)置響應(yīng)頭,告訴瀏覽器要下載文件
// response.setContentType()是設(shè)置響應(yīng)類型的 瀏覽器讀取的是什么文件 依據(jù)文件類型,告訴瀏覽器接下來要做的是什么
// application/octet-stream 告訴瀏覽器需要下載二進(jìn)制流數(shù)據(jù)(如常見的文件下載)
response.setContentType("application/octet-stream");
/**
* response.setHeader("Content-Disposition", "attachment; filename=" +new String( filename.getBytes("gb2312"), "ISO8859-1" ));
* 在確保附件文件名都是簡體中文字的情況下,那么這個(gè)辦法確實(shí)是最有效的,不用讓客戶逐個(gè)的升級(jí)IE。
* 如果臺(tái)灣同胞用,把gb2312改成big5就行。但現(xiàn)在的系統(tǒng)通常都加入了 國際化的支持,普遍使用UTF-8。
* 如果文件名中又有簡體中文字,又有繁體中文,還有日文。那么亂碼便產(chǎn)生了。另外,在上Firefox (v1.0-en)下載也是亂碼。
*/
response.setHeader("Content-Disposition", "attachment; filename=" +new String( filename.getBytes("gb2312"), "ISO8859-1" ));
//response.getOutputStream() 輸出字節(jié)流, 客戶端會(huì)下載字節(jié)流并生成文件保存本地
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(FileUtil.readBytes(file));
outputStream.close();
return "success";
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
JVM內(nèi)存結(jié)構(gòu)相關(guān)知識(shí)解析
這篇文章主要介紹了JVM內(nèi)存結(jié)構(gòu)相關(guān)知識(shí)解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
Java8新特性Stream流中anyMatch和allMatch和noneMatch的區(qū)別解析
這篇文章主要介紹了Java8新特性Stream流中anyMatch和allMatch和noneMatch的區(qū)別解析,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01
使用Post方法模擬登陸爬取網(wǎng)頁的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄褂肞ost方法模擬登陸爬取網(wǎng)頁的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03
JAVA裝飾者模式(從現(xiàn)實(shí)生活角度理解代碼原理)
裝飾者模式可以動(dòng)態(tài)地給一個(gè)對象添加一些額外的職責(zé)。就增加功能來說,Decorator模式相比生成子類更為靈活。這篇文章主要介紹了JAVA裝飾者模式的相關(guān)資料,需要的朋友可以參考下2016-12-12
SpringBoot集成P6Spy的實(shí)現(xiàn)示例
本文主要介紹了SpringBoot集成P6Spy的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-08-08
java正則表達(dá)式實(shí)現(xiàn)提取需要的字符并放入數(shù)組【ArrayList數(shù)組去重復(fù)功能】
這篇文章主要介紹了java正則表達(dá)式實(shí)現(xiàn)提取需要的字符并放入數(shù)組,即基于正則的ArrayList數(shù)組去重復(fù)功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-01-01
詳解@ConfigurationProperties如何裝載到Spring容器中
這篇文章主要為大家詳細(xì)介紹了@ConfigurationProperties該如何裝載到Spring容器中,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考一下2023-07-07

