SpringBoot 文件上传和下载的实现源码

本篇文章介绍SpringBoot的上传和下载功能。

一、创建SpringBoot工程,添加依赖

compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-thymeleaf") 

工程目录为:

Application.java 启动类

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);
  }
} 

二、创建测试页面

在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服务

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实现

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创建

将上传的文件,放到工程的upload-dir目录,默认在界面上列出可以下载的文件。

listUploadedFiles函数,会列出当前目录下的所有文件

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

总结

以上所述是小编给大家介绍的SpringBoot 文件上传和下载的实现源码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 基于Spring Boot的Environment源码理解实现分散配置详解

    前提 org.springframework.core.env.Environment是当前应用运行环境的公开接口,主要包括应用程序运行环境的两个关键方面:配置文件(profiles)和属性.Environment继承自接口PropertyResolver,而PropertyResolver提供了属性访问的相关方法.这篇文章从源码的角度分析Environment的存储容器和加载流程,然后基于源码的理解给出一个生产级别的扩展. 本文较长,请用一个舒服的姿势阅读. Environment类体系 Pr

  • 基于spring-boot和docker-java实现对docker容器的动态管理和监控功能[附完整源码下载]

    docker简介 Docker 是一个开源的应用容器引擎,和传统的虚拟机技术相比,Docker 容器性能开销极低,因此也广受开发者喜爱.随着基于docker的开发者越来越多,docker的镜像也原来越丰富,未来各种企业级的完整解决方案都可以直接通过下载镜像拿来即用.因此docker变得越来越重要. 本文目的 本文通过一个项目实例来介绍如果通过docker对外接口来实现对docker容器的管理和监控. 应用场景: 对服务器资源池通过docker进行统一管理,按需分配资源和创建容器,达到资源最大化利

  • Spring Boot中利用JavaMailSender发送邮件的方法示例(附源码)

    快速入门 在Spring Boot的工程中的pom.xml中引入spring-boot-starter-mail依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> 如其他自动化配置模块一样,在完成了依赖引入之后,只需要在applicatio

  • Springboot源码 TargetSource解析

    摘要: 其实我第一次看见这个东西的时候也是不解,代理目标源不就是一个class嘛还需要封装干嘛... 其实proxy代理的不是target,而是TargetSource,这点非常重要,一定要分清楚!!! 通常情况下,一个代理对象只能代理一个target,每次方法调用的目标也是唯一固定的target.但是,如果让proxy代理TargetSource,可以使得每次方法调用的target实例都不同(当然也可以相同,这取决于TargetSource实现).这种机制使得方法调用变得灵活,可以扩展出很多高

  • 详解Maven 搭建spring boot多模块项目(附源码)

    本文介绍了Maven 搭建spring boot多模块项目,分享给大家,具体如下: 备注:所有项目都在idea中创建 1.idea创建maven项目 1-1: 删除src,target目录,只保留pom.xml 1-2: 根目录pom.xml可被子模块继承,因此项目只是demo,未考虑太多性能问题,所以将诸多依赖.都写在根级`pom.xml`,子模块只需继承就可以使用. 1-3: 根级pom.xml文件在附录1 1-4: 依赖模块 mybatis spring-boot相关模块 2.创建子模块(

  • Springboot源码 AbstractAdvisorAutoProxyCreator解析

    摘要: Spring的代理在上层中主要分为ProxyCreatorSupport和ProxyProcessorSupport,前者是基于代理工厂,后者是基于后置处理器,也可以认为后置就是自动代理器.当spring容器中需要进行aop进行织入的bean较多时,简单采用ProxyFacotryBean无疑会增加很多工作量(因为每个Bean!都得手动写一个).所以自动代理就发挥它的作用了. Spring中自动创建代理器分类 在内部,Spring使用BeanPostProcessor让自动生成代理.基于

  • 详解SpringBoot集成jsp(附源码)+遇到的坑

    本文介绍了SpringBoot集成jsp(附源码)+遇到的坑 ,分享给大家 1.大体步骤 (1)创建Maven web project: (2)在pom.xml文件添加依赖: (3)配置application.properties支持jsp (4)编写测试Controller (5)编写JSP页面 (6)编写启动类App.java 2.新建SpringInitialzr 3.pom文件 <dependencies> <dependency> <groupId>org.s

  • SpringBoot 文件上传和下载的实现源码

    本篇文章介绍SpringBoot的上传和下载功能. 一.创建SpringBoot工程,添加依赖 compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-starter-thymeleaf") 工程目录为: Application.java 启动类 package hello; import org.springf

  • SpringBoot文件上传与下载功能实现详解

    目录 前言 1.引入Apache Commons FileUpload组件依赖 2.设置上传文件大小限制 3.创建选择文件视图页面 4.创建控制器 5.创建文件下载视图页面 前言 文件上传与下载是Web应用开发中常用的功能之一,在实际的Web应用开发中,为了成功上传文件,必须将表单的method设置为post,并将enctype设置为multipart/form-data 只有这样设置,浏览器才能将所选文件的二进制数据发送给服务器 从Servlet3.0开始,就提供了处理文件上传的方法,但这种文

  • 基于QT实现文件上传和下载功能

    本文实例为大家分享了基于QT实现文件上传和下载的具体代码,供大家参考,具体内容如下 功能 支持文件上传功能 支持文件下载功能 支持断点续传功能 支持连续多个文件的上传下载 文件上传下载流程 在确认断点的时候会利用md5进行数据校验,防止数据发生更改. 服务端 采用多线程的Reactor模式.即一个线程对应多个filesocket进行文件上传下载.线程个数可设置,默认为1. FileServer 继承QTcpServer,实现incomingConnection虚函数.当有新的连接到来时,会创建F

  • 详解SpringBoot下文件上传与下载的实现

    SpringBoot后台如何实现文件上传下载? 最近做的一个项目涉及到文件上传与下载.前端上传采用百度webUploader插件.有关该插件的使用方法还在研究中,日后整理再记录.本文主要介绍SpringBoot后台对文件上传与下载的处理. 单文件上传 / 单文件上传 @RequestMapping(value = "/upload") @ResponseBody public String upload(@RequestParam("file") Multipart

  • springboot整合minio实现文件上传与下载且支持链接永久访问

    目录 1.minio部署 2.项目搭建 3.文件上传 4.文件下载 5.文件永久链接下载 1.minio部署 1.1 拉取镜像 docker pull minio/minio 1.2 创建数据目录 mkdir -p /home/guanz/minio mkdir -p /home/guanz/minio/midata 1.3 启动minio docker run -d -p 9000:9000 -p 9001:9001 --restart=always -e MINIO_ACCESS_KEY=g

  • SpringBoot+微信小程序实现文件上传与下载功能详解

    目录 1.文件上传 1.1 后端部分 1.2 小程序前端部分 1.3 实现效果 2.文件下载 2.1 后端部分 2.2 小程序前端部分 2.3 实现效果 1.文件上传 1.1 后端部分 1.1.1 引入Apache Commons FIleUpload组件依赖 <!--文件上传与下载相关的依赖--> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fil

  • SpringBoot实现文件上传与下载功能的示例代码

    目录 Spring Boot文件上传与下载 举例说明 1.引入Apache Commons FileUpload组件依赖 2.设置上传文件大小限制 3.创建选择文件视图页面 4.创建控制器 5.创建文件下载视图页面 6.运行 Spring Boot文件上传与下载 在实际的Web应用开发中,为了成功上传文件,必须将表单的method设置为post,并将enctype设置为multipart/form-data.只有这种设置,浏览器才能将所选文件的二进制数据发送给服务器. 从Servlet 3.0开

  • Axios+Spring Boot实现文件上传和下载

    本文实例为大家分享了Axios+Spring Boot实现文件上传和下载的具体代码,供大家参考,具体内容如下 1.所用技术 前端:Vue + Axios 后端:Springboot + SpringMVC 2.单文件上传 后端代码 只需要使用MultipartFile类配合RequestBody注解即可 @PostMapping("your/path") public ResultData courseCoverUpload(@RequestBody MultipartFile fil

  • java组件commons-fileupload实现文件上传、下载、在线打开

    最近做了一个文件上传.下载.与在线打开文件的功能,刚开始对文件上传的界面中含有其它表单(例如输入框.密码等)在上传的过程中遇到了许多问题,下面我写了一个同时实现文件上传.下载.在线打开文件的测试程序. 首先请看效果图: 核心代码: package com.jefry; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; import java.u

  • MyBatis与SpringMVC相结合实现文件上传、下载功能

    环境:maven+SpringMVC + Spring + MyBatis + MySql 本文主要说明如何使用input上传文件到服务器指定目录,或保存到数据库中:如何从数据库下载文件,和显示图像文件并实现缩放. 将文件存储在数据库中,一般是存文件的byte数组,对应的数据库数据类型为blob. 首先要创建数据库,此处使用MySql数据库. 注意:文中给出的代码多为节选重要片段,并不齐全. 1. 前期准备 使用maven创建一个springMVC+spring+mybatis+mysql的项目

随机推荐