关于SpringBoot项目中的文件上传与文件下载的简单实现

概述

文件上传与下载,是程序开发中经常使用到的一个功能,比如:

  • 用户头像、文章封面等需求
  • 博客中发布文章的富文本编辑框插件文件上传功能

什么是文件上传?文件上传就是为了共享资源
一句话:把用户的自己电脑中的文件,通过程序上传到服务器的过程

如何实现

新建一个spring boot工程

项目结构

pom.xml

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

    </dependencies>

配置文件

server:
  port: 8080

spring:
  freemarker:
    suffix: .html
    cache: false
  servlet:
    multipart:
      enabled: true # 开启文件上传
      file-size-threshold: 2KB # 文件写入磁盘的阈值
      max-file-size: 100MB
      max-request-size: 215MB # 最大请求值大小

# 自定义文件保存路径
gorit:
  file:
    root:
      path: E:\桌面\test\



controller

package com.example.demo.controller;

import com.example.demo.R.Result;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;


@Api(value = "文件上传,下载相关功能")
@RestController
public class FileController {
    // 设置固定的日期格式
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    // 将 yml 中的自定义配置注入到这里
    @Value("${gorit.file.root.path}")
    private String filePath;
    // 日志打印
    private Logger log = LoggerFactory.getLogger("FileController");

    // 文件上传 (可以多文件上传)
    @PostMapping("/upload")
    public Result fileUploads(HttpServletRequest request, @RequestParam("file") MultipartFile file) throws IOException {
        // 得到格式化后的日期
        String format = sdf.format(new Date());
        // 获取上传的文件名称
        String fileName = file.getOriginalFilename();
        // 时间 和 日期拼接
        String newFileName = format + "_" + fileName;
        // 得到文件保存的位置以及新文件名
        File dest = new File(filePath + newFileName);
        try {
            // 上传的文件被保存了
            file.transferTo(dest);
            // 打印日志
            log.info("上传成功,当前上传的文件保存在 {}",filePath + newFileName);
            // 自定义返回的统一的 JSON 格式的数据,可以直接返回这个字符串也是可以的。
            return Result.succ("上传成功");
        } catch (IOException e) {
            log.error(e.toString());
        }
        // 待完成 —— 文件类型校验工作
        return Result.fail("上传错误");
    }

}

返回的R类(统一返回和处理)

package com.example.demo.R;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Result {
    private Object data;
    private String msg;
    private int code;

    // 操作成功返回数据
    public static Result succ(Object data) {
        return succ(200, "操作成功", data);
    }

    public static Result succ(String msg) {
        return succ(200, msg, null);
    }


    public static Result succ(int code, String msg, Object data) {
        Result r = new Result();
        r.setCode(code);
        r.setMsg(msg);
        r.setData(data);
        return r;
    }

    public static Result succ(String msg, Object data) {
        return succ(200,msg,data);
    }

    // 操作异常返回
    public static Result fail(int code, String msg, Object data) {
        Result r = new Result();
        r.setCode(code);
        r.setMsg(msg);
        r.setData(data);
        return r;
    }

    public static Result fail(String msg) {
        return fail(400,msg,null);
    }

    public static Result fail(int code, String msg) {
        return fail(code,msg,"null");
    }

    public static Result fail(String msg, Object data) {
        return fail(400,msg,data);
    }

}

设置静态资源的路径

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 开启 mvc支持,设置 static 目录为类路径
 */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    // 得到 classpath 的根路径, resources 目录下的所以路径都可以得到
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
                .addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");
    }
}


静态页面

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>文件上传</title>
</head>
<body>
<h1>文件上传</h1>

<form action="/upload" enctype="multipart/form-data" method="post">
    <input name="dir" value="bbs">
    <input name="file" type="file">
    <input type="submit" value="文件上传">
</form>
<br><br><br><br>
<h1>文件下载</h1>
<a href="http://localhost:8080/data/demo.html" download="demo.html">点击下载</a>
</body>
</html>

运行测试

访问路径http://localhost:8080/index

文件上传

首页
(请忽略它的丑。。。毕竟只是个小测试)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文件下载

文件下载是访问的我们springboot项目当中的静态资源目录,默认在resourcestatic目录下,也可以通过上面的配置类进行更改静态资源的目录
在这里插入图片描述
在这里插入图片描述
关于文件下载:

<h1>文件下载</h1>
<a href="http://localhost:8080/data/demo.html" download="demo.html">点击下载</a>
</body>

a标签的href
前后端分离项目中,需填写服务器的完整访问接口
在springboot单体项目中,配置了freemarker或thymeleaf模板引擎,可以填写href="data/demo.html"

写在最后

这是我目前见过的实现springboot文件上传功能比较简单的实现方式,写起来非常简洁易懂,若有问题欢迎指正与讨论😁
在这里插入图片描述

  • 14
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值