博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot 2.0 | SpringBoot 文件上传下载
阅读量:4104 次
发布时间:2019-05-25

本文共 6628 字,大约阅读时间需要 22 分钟。

环境与配置

添加 maven 依赖

org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
true

application.yml 配置文件

spring:  servlet:    multipart:      max-file-size: 1024KB # 单个文件大小      max-request-size: 1024KB # 一次请求文件大小

代码

文件上传服务接口 ,实现初始化,存储,查询等方法。

public interface StorageService {    void init();    void store(MultipartFile file);    Stream
loadAll(); Path load(String filename); Resource loadAsResource(String filename); void deleteAll();}

StorageService 接口实现类

@Servicepublic class FileSystemStorageService implements StorageService {    private final Path rootLocation;    @Autowired    public FileSystemStorageService(StorageProperties properties) {        //获取文件存储路径        this.rootLocation = Paths.get(properties.getLocation());    }    //上传文件    @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);            }            try (InputStream inputStream = file.getInputStream()) {                Files.copy(inputStream, this.rootLocation.resolve(filename),                        StandardCopyOption.REPLACE_EXISTING);            }        }        catch (IOException e) {            throw new StorageException("Failed to store file " + filename, e);        }    }        @Override    public Stream
loadAll() { try { return Files.walk(this.rootLocation, 1) .filter(path -> !path.equals(this.rootLocation)) .map(this.rootLocation::relativize); } catch (IOException e) { throw new StorageException("Failed to read stored files", e); } } @Override public Path load(String filename) { return rootLocation.resolve(filename); } @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); } } @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); } }}

文件存储的目录配置,运行项目是会在项目根目录创建 upload-dir 文件夹。

@ConfigurationProperties("storage")public class StorageProperties {    /**     * Folder location for storing files     */    private String location = "upload-dir";    public String getLocation() {        return location;    }    public void setLocation(String location) {        this.location = location;    }}

异常处理

public class StorageException extends RuntimeException {    public StorageException(String message) {        super(message);    }    public StorageException(String message, Throwable cause) {        super(message, cause);    }}
public class StorageFileNotFoundException extends StorageException {    public StorageFileNotFoundException(String message) {        super(message);    }    public StorageFileNotFoundException(String message, Throwable cause) {        super(message, cause);    }}

控制层

@Controllerpublic 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
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://spring.io/guides/gs/uploading-files/@SpringBootApplication@EnableConfigurationProperties(StorageProperties.class)public class SpringBootFileUploadApplication {	public static void main(String[] args) {		SpringApplication.run(SpringBootFileUploadApplication.class, args);	}	//初始化,创建文件夹	@Bean	CommandLineRunner init(StorageService storageService) {		return (args) -> {			storageService.deleteAll();			storageService.init();		};	}}

前端代码 uploadForm.html

File to upload:

项目结构

在这里插入图片描述

运行结果

在这里插入图片描述

公众号:【星尘Pro】

github:

推荐阅读

源码下载:https://github.com/huangliangyun/Spring-Boot-2.X
参考:https://spring.io/guides/gs/uploading-files/
https://github.com/spring-guides/gs-uploading-files

转载地址:http://udfsi.baihongyu.com/

你可能感兴趣的文章
C++学习之普通函数指针与成员函数指针
查看>>
C++的静态成员函数指针
查看>>
Linux系统编程——线程池
查看>>
yfan.qiu linux硬链接与软链接
查看>>
Linux C++线程池实例
查看>>
shared_ptr简介以及常见问题
查看>>
c++11 你需要知道这些就够了
查看>>
c++11 你需要知道这些就够了
查看>>
shared_ptr的一些尴尬
查看>>
C++总结8——shared_ptr和weak_ptr智能指针
查看>>
c++写时拷贝1
查看>>
C++ 写时拷贝 2
查看>>
Linux网络编程---I/O复用模型之poll
查看>>
Java NIO详解
查看>>
单列模式-编写类ConfigManager读取属性文件
查看>>
java中float和double的区别
查看>>
Statement与PreparedStatement区别
查看>>
Tomcat配置数据源步骤以及使用JNDI
查看>>
before start of result set 是什么错误
查看>>
(正则表达式)表单验证
查看>>