Java實(shí)現(xiàn)文件上傳到服務(wù)器本地并通過(guò)url訪(fǎng)問(wèn)的方法步驟
一、場(chǎng)景
Java實(shí)現(xiàn)文件上傳到服務(wù)器本地,并通過(guò)url訪(fǎng)問(wèn)
有個(gè)需求,前端上傳文件,需要用開(kāi)關(guān)的方式同時(shí)支持上傳七牛和服務(wù)器本地,方便不同的用戶(hù)需求合理分配資源。本篇主要介紹文件上傳到本地,然后通過(guò)url訪(fǎng)問(wèn)。
二、SpringBoot默認(rèn)靜態(tài)資源訪(fǎng)問(wèn)方式
首先想到的就是可以通過(guò)SpringBoot通常訪(fǎng)問(wèn)靜態(tài)資源的方式,當(dāng)訪(fǎng)問(wèn):項(xiàng)目根路徑 + / + 靜態(tài)文件名時(shí),SpringBoot會(huì)依次去類(lèi)路徑下的四個(gè)靜態(tài)資源目錄下查找(默認(rèn)配置)。
在資源文件resources目錄下建立如下四個(gè)目錄:
重啟Spring boot,訪(fǎng)問(wèn)
http://localhost:8080/1.jpg
http://localhost:8080/2.jpg
http://localhost:8080/3.jpg
http://localhost:8080/4.jpg
結(jié)果:
三、上傳的文件應(yīng)該存儲(chǔ)在哪?怎么訪(fǎng)問(wèn)?
1.文件存儲(chǔ)在哪?
前文所說(shuō)外部用戶(hù)可通過(guò)url訪(fǎng)問(wèn)服務(wù)器資源文件resources目錄下的靜態(tài)資源,但若是將上傳的文件都保存在resources相關(guān)目錄下,將會(huì)導(dǎo)致后續(xù)打包過(guò)大,程序和代碼不分離,無(wú)法查看等問(wèn)題。
解決方案:文件上傳到服務(wù)器某個(gè)目錄,然后SpringBoot配置虛擬路徑,映射到此目錄。
2.怎么訪(fǎng)問(wèn)?
通過(guò)WebMvcConfigurer 的addResourceHandlers將匹配上虛擬路徑的url映射到文件上傳到服務(wù)器的目錄,這樣就可以通過(guò)url來(lái)獲取服務(wù)器上的靜態(tài)資源了。
示例代碼
目標(biāo):windows本地測(cè)試,將文件上傳到 D:\develop\work\project\myblog\myblog-file-upload\fileStorage 目錄下,然后通過(guò)http://localhost:8080/files/文件名 訪(fǎng)問(wèn)。
配置類(lèi)
@Configuration public class WebMvcConfig implements WebMvcConfigurer { @Autowired FileServiceImpl fileService; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //將匹配上/files/**虛擬路徑的url映射到文件上傳到服務(wù)器的目錄,獲取靜態(tài)資源 registry.addResourceHandler("/" + fileService.pathPattern + "/**").addResourceLocations("file:" + fileService.filePath); WebMvcConfigurer.super.addResourceHandlers(registry); } }
Controller
@RestController @RequestMapping("/file") public class FileController { @Autowired private FileServiceImpl fileService; @PostMapping("/upload") public FileUploadResponse upload(@RequestParam("file") MultipartFile file) { return fileService.upload(file); } }
上傳文件目錄創(chuàng)建好后,主要通過(guò) file.transferTo(new File(absolutePath)) 完成。
Service
@Slf4j @Service public class FileServiceImpl { //攔截的url,虛擬路徑 public String pathPattern = "files"; //自己設(shè)置的目錄 private static final String fileDir = "fileStorage"; //上傳文件存放目錄 = 工作目錄絕對(duì)路徑 + 自己設(shè)置的目錄,也可以直接自己指定服務(wù)器目錄 //windows本地測(cè)試 //絕對(duì)路徑: D:\develop\work\project\myblog\myblog-file-upload\fileStorage\202302021010345680.jpg //System.getProperty("user.dir") D:\develop\work\project\myblog\myblog-file-upload //fileDir fileStorage //fileName 202302021010345680.jpg public String filePath = System.getProperty("user.dir") + File.separator + fileDir + File.separator; private static final AtomicInteger SUFFIX = new AtomicInteger(0); @Value(value = "${file.upload.suffix:jpg,jpeg,png,bmp,xls,xlsx,pdf}") private String fileUploadSuffix; public FileUploadResponse upload(MultipartFile file) { FileUploadResponse result = new FileUploadResponse(); if (file.isEmpty()) { log.error("the file to be uploaded is empty"); return result; } List<String> suffixList = Lists.newArrayList(fileUploadSuffix.split(",")); try { //校驗(yàn)文件后綴 String originalFilename = file.getOriginalFilename(); String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1); if (!suffixList.contains(suffix)) { log.error("unsupported file format"); return result; } //首次需生成目錄 File folder = new File(filePath); if (!folder.exists()) { folder.mkdirs(); } String fileName = timeFormat(System.currentTimeMillis()) + SUFFIX.getAndIncrement() + "." + suffix; String absolutePath = filePath + fileName; log.info("absolutePath is {}", absolutePath); file.transferTo(new File(absolutePath)); String separator = "/"; String path = separator + pathPattern + separator + fileName; result.setPath(path); result.setFileName(fileName); } catch (Exception e) { log.error("the file upload error occurred. e ", e); } return result; } public static String timeFormat(Long time) { if (Objects.isNull(time)) { return null; } DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); return sdf.format(time); } }
四、測(cè)試
查看文件夾,已上傳成功
將上傳接口返回的path拼接上域名或者ip端口、訪(fǎng)問(wèn) http://localhost:8080/files/202302021010345680.jpg,得到:
五、總結(jié)
其實(shí)這和最初的SpringBoot獲取靜態(tài)資源的方式又有點(diǎn)不一樣,針對(duì)url做攔截,實(shí)際上resources目錄下并沒(méi)有files這個(gè)文件夾,它只是一個(gè)虛擬路徑,通過(guò)映射轉(zhuǎn)發(fā)到文件夾上傳目錄,在該目錄下通過(guò)文件名去定位。
另外,如果有用nginx,也可以在其配置中設(shè)置轉(zhuǎn)發(fā)。
到此這篇關(guān)于Java實(shí)現(xiàn)文件上傳到服務(wù)器本地并通過(guò)url訪(fǎng)問(wèn)的文章就介紹到這了,更多相關(guān)Java文件上傳到服務(wù)器本地并訪(fǎng)問(wèn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaWeb踩坑記錄之項(xiàng)目訪(fǎng)問(wèn)不到html文件
- 使用Java7的Files工具類(lèi)和Path接口來(lái)訪(fǎng)問(wèn)文件的方法
- Java編程利用socket多線(xiàn)程訪(fǎng)問(wèn)服務(wù)器文件代碼示例
- Spring MVC訪(fǎng)問(wèn)靜態(tài)文件_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Java class文件格式之訪(fǎng)問(wèn)標(biāo)志信息_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- Java訪(fǎng)問(wèn)Hadoop分布式文件系統(tǒng)HDFS的配置說(shuō)明
- Java文件拒絕訪(fǎng)問(wèn)問(wèn)題及解決
相關(guān)文章
Redis實(shí)現(xiàn)商品秒殺功能頁(yè)面流程
這篇文章主要介紹了Redis實(shí)現(xiàn)商品秒殺功能的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09SpringBoot+WebSocket實(shí)現(xiàn)多人在線(xiàn)聊天案例實(shí)例
本文主要介紹了SpringBoot+WebSocket實(shí)現(xiàn)多人在線(xiàn)聊天案例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02java 最新Xss攻擊與防護(hù)(全方位360°詳解)
這篇文章主要介紹了java 最新Xss攻擊與防護(hù)(全方位360°詳解),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01關(guān)于maven全局配置文件settings.xml解析
這篇文章主要介紹了關(guān)于maven全局配置文件settings.xml,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2022-03-03Spring Cloud 專(zhuān)題之Sleuth 服務(wù)跟蹤實(shí)現(xiàn)方法
這篇文章主要介紹了Spring Cloud 專(zhuān)題之Sleuth 服務(wù)跟蹤,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-08-08