8、SpringMVC-文件上傳

一、導(dǎo)包相關(guān)包

<!-- 文件上傳核心包 -->
<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>${fileupload.version}</version>
</dependency>
<!-- 工具包 -->
<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-lang3</artifactId>
  <version>${commons-lang.version}</version>
</dependency>

二、栗子

控制層

@RestController
public class UploaderController {
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public String uploadSingleFile(@RequestParam("img") MultipartFile multipartFile) throws IOException {
        String imagePath = UploadUtils.saveImage(multipartFile);
        return imagePath;
    }
    @RequestMapping(value = "/uploads", method = RequestMethod.POST)
    public List<String> uploadMultipartFile(@RequestParam("img") MultipartFile[] multipartFiles) throws IOException {
        List<String> imgList = new ArrayList<>();
        for (MultipartFile multipartFile : multipartFiles) {
            String imagePath = UploadUtils.saveImage(multipartFile);
            imgList.add(imagePath);
        }
        return imgList;
    }
}

上傳工具類

public class UploadUtils {
    public static final String SAVE_IMG_FILE = "images";
    public static String saveImage(MultipartFile multipartFile) throws IOException {
        // 通過配置文件獲取保存的路徑  注意上線的時(shí)候要修改成服務(wù)器保存的絕對路徑
        ResourceBundle bundle = ResourceBundle.getBundle("sys");
        //獲取到了跟路徑
        String rootPath = bundle.getString("root.upload.path");
        // 獲取保存圖片名字的統(tǒng)一前綴
        String imgSuffix = bundle.getString("img.suffix");
        // 生成圖片保存路徑 根據(jù)日期保存
        String imagePath = String.format("%s%s%s", SAVE_IMG_FILE, File.separator, DateFormatUtils.format(new Date(), "yyyyMMdd"));
        /**
         * 保存到服務(wù)器數(shù)據(jù)庫的路徑
         */
        String savePath = String.format("%s%s%s", imagePath, File.separator, getFileName(imgSuffix, multipartFile.getOriginalFilename()));
        // 拼接保存的路徑
        //     根路勁  +  業(yè)務(wù)需求的路徑 +  文件名
        File imgFile = new File(String.format("%s%s%s",rootPath,File.separator ,savePath));
        // 創(chuàng)建保存圖片的文件
        FileUtils.touch(imgFile);
        // 將客服端圖片寫到文件中
        FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), imgFile);
        return savePath;
    }
    /**
     * 獲取
     * @param oldName
     * @return
     */
    public static String getFileName(String suffixName, String oldName) {
        // 對圖片進(jìn)行重命名
        String prefix = suffixName + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss");
        String suffix = oldName.substring(oldName.indexOf("."));
        return prefix + suffix;
    }
}

配置文件

sys.properties

# 文件大小最大值 單位kb 50M
maxUploadSize=52428800
# 單個(gè)文件限制大小 5m
maxUploadSizePerFile=5242880
# 設(shè)置文件編碼
defaultEncoding = UTF-8
# 文件上傳相關(guān)路徑
# 主路徑  修改成你自己的
root.upload.path=/Users/xxx/xxx/upload
img.suffix = IMG_
file_suffix = FILE_

mvc配置文件

<!--注意id的值是固定的 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
    <!-- 默認(rèn)編碼 -->
    <property name="defaultEncoding" value="${defaultEncoding}" />
    <!-- 文件大小最大值 -->
    <property name="maxUploadSize" value="${maxUploadSize}" />
    <!--    單個(gè)文件限制大小 -->
    <property name="maxUploadSizePerFile" value="${maxUploadSizePerFile}"/>
    <!-- 內(nèi)存中緩存的最大值 -->
    <property name="maxInMemorySize" value="${maxInMemorySize}" />
<!-- 為true時(shí),啟用推遲文件解析,以便在UploadAction中捕獲文件大小異常-->
    <property name="resolveLazily" value="${resolveLazily}"/>
</bean>

前端

  • 為了能上傳文件,必須將表單的method設(shè)置為POST或者PUT
  • 并將enctype設(shè)置為multipart/form-data
    普通表單
<h2>單文件上傳</h2>
<form id='uploadForm' method="post" enctype="multipart/form-data">
    <input type="file" name="img">
    <button id='upload'>上傳</button>
</form>
<h2>多文件上傳</h2>
<form method="post" enctype="multipart/form-data">
    <input type="file" name="imgs" multiple>
  <button id='upload'>上傳</button>
</form>

ajax

$('#upload').click(function () {
   let formData = new FormData($('#uploadForm')[0]);
    $.ajax({
        url:'http://localhost:8080/upload/',
        dataType:'json',
        type:'POST',
        data: formData,
         // 使數(shù)據(jù)不做處理
        processData : false,
        // 不要設(shè)置Content-Type請求頭
        contentType : false,
        success: function(data){
            if (data.status == 'ok') {
                alert('上傳成功!');
            }
        },
        error:function(response){
            console.log(response);
        }
    });
})

三、核心類介紹

MultipartFile

方法 說明
InputStream getInputStream() 獲取文件流
getOriginalFilename() 獲取上傳文件的原名
boolean isEmpty() 判斷文件是否為空
void transferTo(File dest) 保存文件到指定的文件中,注意父路徑一定要存在
String getContentType() 獲取文件MIME類型

CommonsMultipartResolver

屬性 說明
uploadTempDir 設(shè)置上傳文件時(shí)的臨時(shí)目錄,默認(rèn)是Servlet容器的臨時(shí)目錄。
maxUploadSize 設(shè)置允許上傳的總的最大文件大小,以字節(jié)為單位計(jì)算。當(dāng)設(shè)為-1時(shí)表示無限制,默認(rèn)是-1
maxUploadSizePerFile maxUploadSizePerFile是限制每個(gè)上傳文件的大小
maxInMemorySize 設(shè)置在文件上傳時(shí)允許寫到內(nèi)存中的最大值,以字節(jié)為單位計(jì)算,默認(rèn)是10240
resolveLazily 為true時(shí),啟用推遲文件解析,以便在UploadAction中捕獲文件大小異常。
defaultEncoding 表示用來解析request請求的默認(rèn)編碼格式,當(dāng)沒有指定的時(shí)候根據(jù)有些時(shí)候Servlet規(guī)范會使用默認(rèn)值ISO-8859-1。當(dāng)request自己指明了它的編碼格式的時(shí)候就會忽略這里指定的

?

四、總結(jié)

前端

  • 請求方式一定要是post請求或者put請求
  • 請求的conentType必須是 multipart/form-data

文件

  • 對圖片進(jìn)行重命名,一般根據(jù)時(shí)間戳或者uuid生成規(guī)則,避免文件覆蓋的現(xiàn)象
  • 保存的路徑也根據(jù)實(shí)際的業(yè)務(wù)場景來動態(tài)生成

多文件上傳

  • 使用MultipartFile[]數(shù)組來接受,使用集合來接受保存的路徑
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容