SpringBoot 文件上傳和下載的實(shí)現(xiàn)源碼
本篇文章介紹SpringBoot的上傳和下載功能。
一、創(chuàng)建SpringBoot工程,添加依賴
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-thymeleaf")
工程目錄為:

Application.java 啟動(dòng)類
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
二、創(chuàng)建測(cè)試頁(yè)面
在resources/templates目錄下新建uploadForm.html
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:if="${message}">
<h2 th:text="${message}"/>
</div>
<div>
<form method="POST" enctype="multipart/form-data" action="/">
<table>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td></td><td><input type="submit" value="Upload" /></td></tr>
</table>
</form>
</div>
<div>
<ul>
<li th:each="file : ${files}">
<a th:href="${file}" rel="external nofollow" th:text="${file}" />
</li>
</ul>
</div>
</body>
</html>
三、新建StorageService服務(wù)
StorageService接口
package hello.storage;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.stream.Stream;
public interface StorageService {
void init();
void store(MultipartFile file);
Stream<Path> loadAll();
Path load(String filename);
Resource loadAsResource(String filename);
void deleteAll();
}
StorageService實(shí)現(xiàn)
package hello.storage;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.function.Predicate;
import java.util.stream.Stream;
@Service
public class FileSystemStorageService implements StorageService
{
private final Path rootLocation = Paths.get("upload-dir");
/**
* 保存文件
*
* @param file 文件
*/
@Override
public void store(MultipartFile file)
{
String filename = StringUtils.cleanPath(file.getOriginalFilename());
try
{
if (file.isEmpty())
{
throw new StorageException("Failed to store empty file " + filename);
}
if (filename.contains(".."))
{
// This is a security check
throw new StorageException("Cannot store file with relative path outside current directory " + filename);
}
Files.copy(file.getInputStream(), this.rootLocation.resolve(filename), StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e)
{
throw new StorageException("Failed to store file " + filename, e);
}
}
/**
* 列出upload-dir下面所有文件
* @return
*/
@Override
public Stream<Path> loadAll()
{
try
{
return Files.walk(this.rootLocation, 1) //path -> !path.equals(this.rootLocation)
.filter(new Predicate<Path>()
{
@Override
public boolean test(Path path)
{
return !path.equals(rootLocation);
}
});
}
catch (IOException e)
{
throw new StorageException("Failed to read stored files", e);
}
}
@Override
public Path load(String filename)
{
return rootLocation.resolve(filename);
}
/**
* 獲取文件資源
* @param filename 文件名
* @return Resource
*/
@Override
public Resource loadAsResource(String filename)
{
try
{
Path file = load(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable())
{
return resource;
}
else
{
throw new StorageFileNotFoundException("Could not read file: " + filename);
}
}
catch (MalformedURLException e)
{
throw new StorageFileNotFoundException("Could not read file: " + filename, e);
}
}
/**
* 刪除upload-dir目錄所有文件
*/
@Override
public void deleteAll()
{
FileSystemUtils.deleteRecursively(rootLocation.toFile());
}
/**
* 初始化
*/
@Override
public void init()
{
try
{
Files.createDirectories(rootLocation);
}
catch (IOException e)
{
throw new StorageException("Could not initialize storage", e);
}
}
}
StorageException.java
package hello.storage;
public class StorageException extends RuntimeException {
public StorageException(String message) {
super(message);
}
public StorageException(String message, Throwable cause) {
super(message, cause);
}
}
StorageFileNotFoundException.java
package hello.storage;
public class StorageFileNotFoundException extends StorageException {
public StorageFileNotFoundException(String message) {
super(message);
}
public StorageFileNotFoundException(String message, Throwable cause) {
super(message, cause);
}
}
四、Controller創(chuàng)建
將上傳的文件,放到工程的upload-dir目錄,默認(rèn)在界面上列出可以下載的文件。
listUploadedFiles函數(shù),會(huì)列出當(dāng)前目錄下的所有文件
serveFile下載文件
handleFileUpload上傳文件
package hello;
import java.io.IOException;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import hello.storage.StorageFileNotFoundException;
import hello.storage.StorageService;
@Controller
public class FileUploadController {
private final StorageService storageService;
@Autowired
public FileUploadController(StorageService storageService) {
this.storageService = storageService;
}
@GetMapping("/")
public String listUploadedFiles(Model model) throws IOException {
model.addAttribute("files", storageService.loadAll().map(
path -> MvcUriComponentsBuilder.fromMethodName(FileUploadController.class,
"serveFile", path.getFileName().toString()).build().toString())
.collect(Collectors.toList()));
return "uploadForm";
}
@GetMapping("/files/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> serveFile(@PathVariable String filename) {
Resource file = storageService.loadAsResource(filename);
return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + file.getFilename() + "\"").body(file);
}
@PostMapping("/")
public String handleFileUpload(@RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) {
storageService.store(file);
redirectAttributes.addFlashAttribute("message",
"You successfully uploaded " + file.getOriginalFilename() + "!");
return "redirect:/";
}
@ExceptionHandler(StorageFileNotFoundException.class)
public ResponseEntity<?> handleStorageFileNotFound(StorageFileNotFoundException exc) {
return ResponseEntity.notFound().build();
}
}
源碼下載:https://github.com/HelloKittyNII/SpringBoot/tree/master/SpringBootUploadAndDownload
總結(jié)
以上所述是小編給大家介紹的SpringBoot 文件上傳和下載的實(shí)現(xiàn)源碼,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- SpringBoot+ruoyi框架文件上傳和下載的實(shí)現(xiàn)
- SpringBoot實(shí)現(xiàn)文件上傳下載實(shí)時(shí)進(jìn)度條功能(附源碼)
- SpringBoot+微信小程序?qū)崿F(xiàn)文件上傳與下載功能詳解
- springboot整合minio實(shí)現(xiàn)文件上傳與下載且支持鏈接永久訪問
- springboot+vue實(shí)現(xiàn)文件上傳下載
- springboot操作阿里云OSS實(shí)現(xiàn)文件上傳,下載,刪除功能
- 詳解SpringBoot下文件上傳與下載的實(shí)現(xiàn)
- SpringBoot后臺(tái)實(shí)現(xiàn)文件上傳下載
- SpringBoot集成Hadoop實(shí)現(xiàn)文件的上傳和下載功能
相關(guān)文章
識(shí)別率很高的java文字識(shí)別技術(shù)
這篇文章主要為大家詳細(xì)介紹了識(shí)別率很高的java文字識(shí)別技術(shù),親測(cè),希望對(duì)大家有幫助,感興趣的小伙伴們可以參考一下2016-08-08
SpringBoot @ControllerAdvice 攔截異常并統(tǒng)一處理
這篇文章主要介紹了SpringBoot @ControllerAdvice 攔截異常并統(tǒng)一處理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Java 轉(zhuǎn)型(向上或向下轉(zhuǎn)型)詳解及簡(jiǎn)單實(shí)例
這篇文章主要介紹了Java 轉(zhuǎn)型(向上或向下轉(zhuǎn)型)詳解及簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02
Java實(shí)現(xiàn)簡(jiǎn)單的迷宮游戲詳解
迷宮游戲作為經(jīng)典的小游戲,一直深受大家的喜愛。本文小編將為大家詳細(xì)介紹一下如何用Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單的迷宮小游戲,感興趣的可以動(dòng)手試一試2022-02-02
關(guān)于swagger配置及踩坑@Api參數(shù)postion無效解決接口排序問題
這篇文章主要介紹了關(guān)于swagger配置及踩坑@Api參數(shù)postion無效解決接口排序問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
Spring Cloud負(fù)載均衡及遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解
這篇文章主要介紹了Spring Cloud負(fù)載均衡及遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
jdbc實(shí)現(xiàn)用戶注冊(cè)功能代碼示例
這篇文章主要介紹了jdbc實(shí)現(xiàn)用戶注冊(cè)功能,分享了相關(guān)代碼示例,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01

