日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

springboot文件上传服务器,SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)

發(fā)布時(shí)間:2025/3/15 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot文件上传服务器,SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本次的項(xiàng)目環(huán)境為 SpringBoot 2.0.4, JDK8.0. 服務(wù)器環(huán)境為CentOS7.0, Nginx的忘了版本.

前言

SpringBoot使用MultiPartFile接收來(lái)自表單的file文件,然后進(jìn)行 服務(wù)器 的上傳是一個(gè)項(xiàng)目最基本的需求,我以前的項(xiàng)目都是基于SpringMVC框架搭建的,所以在使用SpringBoot的時(shí)候進(jìn)行MultiPartFile上傳遇到了坑,這里說(shuō)一下,其中主要包含兩個(gè)坑點(diǎn).

使用transferTo()方法寫(xiě)入File時(shí)找不到文件路徑.

訪問(wèn)文件時(shí) Nginx 的403 forbidden問(wèn)題.

使用transferTo()方法寫(xiě)入File時(shí)找不到文件路徑

在我們解決問(wèn)題之前,我們先看一下封裝的上傳方法以及報(bào)錯(cuò)日志.

public static final String BASE_PATH = "/test/";

public static String upload(MultipartFile imageFile) {

if (imageFile.isEmpty()) {

return null;

}

String filename = imageFile.getOriginalFilename();

String ext= null;

if(filename.contains(".")){

ext = filename.substring(filename.lastIndexOf("."));

}else{

ext = "";

}

String uuid = UUID.randomUUID().toString().replaceAll("-", "");

String nfileName = uuid + ext;

String dirPath = DateFormatUtils.format(new Date(), "yyyyMMdd");

String filepath = BASE_PATH.endsWith("/") ? BASE_PATH+dirPath : BASE_PATH+"/"+dirPath;

File targetFile = new File(filepath, nfileName);

if (!targetFile.exists()) {

targetFile.mkdirs();

} else {

targetFile.delete();

}

try {

imageFile.transferTo(targetFile);

} catch (IllegalStateException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

String accessUrl = "/"+nfileName;

logger.debug("上傳文件成功 URL:" + nfileName);

return accessUrl;

}

報(bào)錯(cuò)日志如下所示.

java.io.IOException: java.io.FileNotFoundException: /test/20181025/be3676dffca94c6dac5e96a1a41dcd97.jpg (Is a directory)

at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:122)

at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile.transferTo(StandardMultipartHttpServletRequest.java:255)

at com.dong.runline.common.utils.UploadUtils.upload(UploadUtils.java:56)

at com.dong.runline.controller.TimeLineController.createTimeLineAction(TimeLineController.java:55)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

at java.lang.reflect.Method.invoke(Method.java:498)

這里就出現(xiàn)了 java.io.FileNotFoundException 錯(cuò)誤,這是怎么造成的呢?,通過(guò)Debug下的斷點(diǎn)我們發(fā)現(xiàn)是下面的位置發(fā)生了錯(cuò)誤.

這里我用的本地環(huán)境進(jìn)行了測(cè)試,發(fā)現(xiàn)本地創(chuàng)建了這個(gè)樣的一個(gè)路徑,最后的圖片被創(chuàng)建成一個(gè)這樣的路徑.

在SpringMVC環(huán)境下并沒(méi)有這樣的問(wèn)題,在SpringBoot卻出現(xiàn)了這樣的問(wèn)題,那么到底怎么造成的呢?網(wǎng)上的很多博客寫(xiě)到,通過(guò)查詢transferTo()方法源碼找到了問(wèn)題關(guān)鍵所在.

@Override

public void transferTo(File dest) throws IOException, IllegalStateException {

this.part.write(dest.getPath());

}

我們接著進(jìn)入write()方法.

@Override

public void write(String fileName) throws IOException {

File file = new File(fileName);

if (!file.isAbsolute()) {

file = new File(location, fileName);

}

try {

fileItem.write(file);

} catch (Exception e) {

throw new IOException(e);

}

}

這時(shí)候我們看到如果!file.isAbsolute()成立,也就是我們沒(méi)有使用絕對(duì)路徑,那么file = new File(location,fileName);會(huì)在原來(lái)的基礎(chǔ)上加上location路徑.這就是原因所在,解決起來(lái)也很方便,網(wǎng)上總共有兩種方案.

使用絕對(duì)路徑

修改location的值

第一種方案我們就不過(guò)多解釋了,我們看一下如何修改location的值.我們只需要在啟動(dòng)類中注入如下Bean即可.把路徑指向我們的存儲(chǔ)路徑.

@Bean

MultipartConfigElement multipartConfigElement() {

MultipartConfigFactory factory = new MultipartConfigFactory();

factory.setLocation(UploadUtils.BASE_PATH);

return factory.createMultipartConfig();

}

然后我們?cè)傩薷南耈ploadUtils中的創(chuàng)建File方法即可.

String uuid = UUID.randomUUID().toString().replaceAll("-", "");

String nfileName = uuid + ext;

File targetFile = new File(nfileName);

if (!targetFile.exists()) {

targetFile.mkdirs();

} else {

targetFile.delete();

}

訪問(wèn)文件時(shí)Nginx的403 forbidden問(wèn)題

所謂的Nginx的403錯(cuò)誤其實(shí)就是訪問(wèn)權(quán)限錯(cuò)誤.當(dāng)前用戶沒(méi)有訪問(wèn)該資源的權(quán)限,這樣理解的話,我們就有兩種方案可行.一,降低文件訪問(wèn)的權(quán)限等級(jí).二,升高用戶的訪問(wèn)權(quán)限.下面我們一個(gè)一個(gè)來(lái)看一下如何進(jìn)行實(shí)現(xiàn).

降低文件訪問(wèn)的權(quán)限等級(jí)

降低文件的訪問(wèn)權(quán)限,我們只需要用到 chmod指令即可.這里簡(jiǎn)單解釋一下chmod指令.

在Mac的使用過(guò)程中我們也經(jīng)常會(huì)修改 某個(gè)文件的權(quán)限,例如:

chmod 777 file

如果如上設(shè)置的話,那么任何一個(gè)用戶都會(huì)對(duì)這個(gè)file文件擁有全部權(quán)限.

那么為什么是三位數(shù)呢?這是因?yàn)檫@三位數(shù)分別代表著檔案擁有者User、群組Group、其他Other三者的權(quán)限.也就是說(shuō)擁有者的權(quán)限等級(jí)為7,群組的權(quán)限等級(jí)為7,其他權(quán)限等級(jí)也為7.

那么為什么是7呢?這是因?yàn)橐粋€(gè) linux 文件總共有三種權(quán)限,分別是讀r,寫(xiě)w,操作x.對(duì)應(yīng)的值分別是4,2,1.當(dāng)一個(gè)用戶對(duì)某個(gè)文件擁有7的數(shù)值時(shí),這時(shí)候?yàn)?+2+1,也就是說(shuō)他擁有該文件全部的權(quán)限.

上面說(shuō)了 chmod指令的如何使用,那么接下來(lái)我們就可以對(duì)服務(wù)器的文件使用chmod 664 file指令,然后降低文件訪問(wèn)的權(quán)限等級(jí).使全部用戶都擁有文件的訪問(wèn)權(quán)限.但是問(wèn)題來(lái)了,難道用戶上傳一次,我們就需要手動(dòng)修改一次文件的權(quán)限,這顯然是不正確的,那么我們?cè)撛趺崔k呢?這時(shí)候我們就需要提高用戶的訪問(wèn)權(quán)限了.

升高用戶的訪問(wèn)權(quán)限

提高用戶的訪問(wèn)權(quán)限,這里其實(shí)是修改Nginx的啟動(dòng)者,我們把啟動(dòng)者設(shè)置為最多權(quán)限者,那么我們就可以訪問(wèn)到文件了.

首先我們先看是誰(shuí)啟動(dòng)了Nginx需要用到如下的指令.

ps aux | grep "nginx: worker process" | awk '{print $1}'

這里我已經(jīng)做了修改,截圖如下所示.

本來(lái)要是不對(duì)Nginx的配置進(jìn)行任何設(shè)置訪問(wèn)的話,那么第一個(gè)root應(yīng)該為nobody,也就是Nginx的啟動(dòng)者.先前已經(jīng)使用** ls -l file **指令查詢了文件的權(quán)限情況,root 擁有讀寫(xiě)權(quán)限,other沒(méi)有任何權(quán)限.所以我們要把啟動(dòng)者改為root即可.

打開(kāi)Nginx配置文件所在的位置,{nginx}表示你的nginx安裝路徑.

vi {nginx}/conf/nginx.conf

添加啟動(dòng)者,如下所示.

user root

返回到sbin目錄中,準(zhǔn)備檢測(cè)配置文件和重新啟動(dòng)Ngnix.

cd ../sbin/

檢測(cè)配置文件的正確性

./nginx -t

檢測(cè)沒(méi)有任何問(wèn)題,重新啟動(dòng)

./nginx -s reload

這時(shí)候即可正常訪問(wèn)到文件了.

結(jié)語(yǔ)

這篇博客算是日常的問(wèn)題收集吧,整理一下.沒(méi)什么可多說(shuō)的,就是搞事.歡迎關(guān)注騷棟

作者:神經(jīng)騷棟

鏈接:https://www.jianshu.com/p/d8666f2e698f

總結(jié)

以上是生活随笔為你收集整理的springboot文件上传服务器,SpringBoot: 浅谈文件上传和访问的坑 (MultiPartFile)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。