IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot上传和下载文件(二十七) -> 正文阅读

[Java知识库]SpringBoot上传和下载文件(二十七)

当死亡来临,每一个人都不会接受自己的命运,他们会反抗.

上一章简单介绍了SpringBoot启用Https(二十六),如果没有看过,请观看上一章

文件上传和下载,是常用的功能

可以看老蝴蝶以前写的文章: SpringMVC的单文件上传,多文件上传和下载文件(十二)

一. SpringBoot 上传和下载前期准备

创建项目,按照 整合 Thymeleaf 的项目结构来.

关于 SpringBoot 如何整合Thymeleaf ,
可以看老蝴蝶以前写的文章: SpringBoot整合Thymeleaf(十三)

一. 一 创建页面 index.html

index.html

<!doctype html>
<!--注意:引入thymeleaf的名称空间-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type"content="text/html;charset=UTF-8">
    <title>文件上传</title>
    <link rel="StyleSheet" href="webjars/bootstrap/3.4.1/css/bootstrap.css" type="text/css">
</head>
<body class="container">
<p class="h1">上传文件</p>
<form  action="upload" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <div class="custom-file">
            <input type="file" class="custom-file-input" id="file" name="file">
            <label class="file-label" for="file">选择文件</label>
        </div>
    </div>
    <button type="submit" class="btn btn-primary">上传</button>
</form>

<p class="h1">文件下载</p>

<a href="download?fileName=yjl.p12">文件下载 yjl.p12</a>

<script type="text/javascript" src="webjars/jquery/3.5.1/jquery.js"></script>
<script type="text/javascript" src="webjars/bootstrap/3.4.1/js/bootstrap.js"></script>
</body>
</html>

对应的页面效果如下:

image-20211108200245117

一.二 Controller

FileController.java

@Controller
public class FileController {
    //跳转到 index.html 页面
    @RequestMapping("/")
    public String index(){
        return "index";
    }
}

二. 上传文件

二.一 request 放置上传文件

采用以前的 request 获取文件:

    @PostMapping("/upload")
    @ResponseBody
    public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
        // 获得 classpath 的绝对路径
        String realPath = request.getServletContext().getRealPath("static/files");
        File newFile = new File(realPath);
        // 如果文件夹不存在、则新建
        if (!newFile.exists()){
            newFile.mkdirs();
        }
        // 上传
        file.transferTo(new File(newFile, file.getOriginalFilename()));
        String uploadPath=realPath+File.separator+file.getOriginalFilename();
        return "上传文件成功,地址为:"+uploadPath;
    }

页面访问 index, 选择文件,进行上传

image-20211108200850896

会上传成功,返回的路径是:

image-20211108201135637

可以发现,这是一个临时的文件

image-20211108201247283

一般都不放置在临时目录下

二.二 放置在该项目类路径下

修改 realPath 路径值,放置在 classpath 路径下

//String realPath = request.getServletContext().getRealPath("static/files");
  String realPath = ResourceUtils.getURL("classpath:").getPath()+"static/files";

重新上传文件:

image-20211108201626068

放置在本项目的 target 目录下

image-20211108201708233

当执行 mvn clean ,重启服务器等操作时,上传的文件会被清空.

一般都放置在磁盘上,目录的位置由用户指定.

二.三 上传到指定的目录下

二.三.一 application.yml 配置变量,指定目录

application.yml

server:
  port: 8081
  servlet:
    context-path: /File
# 指定目录
uploadFilePath: D:/upload

放置在 D 盘下的 upload 目录下

二.三.二 通过 @Value 等属性注入并使用上传目录

@Controller
public class FileController {

    @Value("${uploadFilePath:D:}")
    private String uploadFilePath;

    @RequestMapping("/")
    public String index(){
        return "index";
    }
    @PostMapping("/upload")
    @ResponseBody
    public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
        // 获得 classpath 的绝对路径
       //String realPath = request.getServletContext().getRealPath("static/files");
       //String realPath = ResourceUtils.getURL("classpath:").getPath()+"static/files";
        String realPath =uploadFilePath;
        File newFile = new File(realPath);
        // 如果文件夹不存在、则新建
        if (!newFile.exists()){
            newFile.mkdirs();
        }
        // 上传
        file.transferTo(new File(newFile, file.getOriginalFilename()));
        String uploadPath=realPath+File.separator+file.getOriginalFilename();
        return "上传文件成功,地址为:"+uploadPath;
    }
}

重新上传文件

image-20211108202112822

image-20211108202146574

这样,重启服务器等操作,就不会删除掉以前的上传文件了.

二.四 配置上传的文件大小

我们上传 yjl.p12 只有 2kb , 可以正确的上传

我们上传这个文件, 9.5M

image-20211108202319033

image-20211108202509852

后端控制台报错

org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.

超过了允许的默认大小,上传失败

二.四.一 配置tomcat 上传大小

spring:
  # 配置thymeleaf的相关信息
  thymeleaf:
    # 开启视图解析
    enabled: true
    #编码格式
    encoding: UTF-8
    #前缀配置
    prefix: classpath:/templates/
    # 后缀配置
    suffix: .html
    #是否使用缓存 开发环境时不设置缓存
    cache: false
    # 格式为 HTML 格式
    mode: HTML5
    # 配置类型
    servlet:
      content-type: text/html
  #配置上传的文件信息
  servlet:
    multipart:
      max-file-size: 100MB   # 服务器端文件大小限制
      max-request-size: 100MB  # 客户端请求文件大小限制

默认的值为: 1m

image-20211108202805352

二.四.二 重新上传测试

重启项目,再次上传

image-20211108202911594

上传文件成功.

image-20211108202942440

二.五 上传文件时传入其它的参数

   /**
     * 上传文件时,同时传入参数的信息.
     * @date 2021/11/4 21:12
     * @author zk_yjl
     * @return
     */
    @PostMapping("/uploadParam")
    @ResponseBody
    public String uploadParam(@RequestParam MultipartFile file,@RequestParam String name,
                              @RequestParam Integer age) throws IOException {
        String realPath =uploadFilePath;
        File newFile = new File(realPath);
        System.out.println("传入的name参数值:"+name+",传入的age参数值:"+age);
        // 如果文件夹不存在、则新建
        if (!newFile.exists()){
            newFile.mkdirs();
        }
        // 上传
        file.transferTo(new File(newFile, file.getOriginalFilename()));
        String uploadPath=realPath+"/"+file.getOriginalFilename();
        return "上传文件成功,地址为:"+uploadPath;
    }

通过 @RequestParam 注解进行指定

我们采用 postman 方式进行测试

image-20211108203256332

postman 上传文件,可以看: 使用PostMan上传文件

发送请求:

查看控制台打印信息:

传入的name参数值:两个蝴蝶飞,传入的age参数值:26

三. 下载文件

传入文件的路径 (包括名称) 进行下载.

  @GetMapping("download")
    public void download(String fileName, HttpServletResponse response) throws IOException {
        // 获得待下载文件所在文件夹的绝对路径
        String realPath =uploadFilePath;
        // 获得文件输入流
        FileInputStream inputStream = new FileInputStream(new File(realPath, fileName));
        // 设置响应头、以附件形式打开文件
        response.setHeader("content-disposition", "attachment; fileName=" + fileName);
        ServletOutputStream outputStream = response.getOutputStream();
        int len = 0;
        byte[] data = new byte[1024];
        while ((len = inputStream.read(data)) != -1) {
            outputStream.write(data, 0, len);
        }
        outputStream.close();
        inputStream.close();
    }

前端点击文件下载,便可以进行下载

image-20211108204637728

四. 文件上传和下载- Excel

项目开发中,常常将数据从 Excel 中导入, 将数据导出成 Excel.

我们用 alibaba 的 easyExcel 进行处理.

四.一 pom.xml 添加依赖

   <!--添加easyExcel 上传excel文件-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>2.2.9</version>
        </dependency>

四.二 实体 User 定义

@Data
public class User {
    @ExcelProperty(value="id编号")
    private Integer id;
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("性别")
    private String sex;
    @ExcelProperty("年龄")
    private Integer age;
    @ExcelProperty("描述信息")
    private String description;
}

上传的文件内容是: 员工表.xlsx

image-20211108205323839

四.三 上传Excel文件

   /**
     * 上传Excel文件,获取文件里面的内容.
     * @date 2021/11/4 21:12
     * @author zk_yjl
     * @return
     */
    @PostMapping("/uploadExcel")
    @ResponseBody
    public String uploadExcel(@RequestParam MultipartFile file) throws IOException {
        String realPath =uploadFilePath;
        File newFile = new File(realPath);
        // 如果文件夹不存在、则新建
        if (!newFile.exists()){
            newFile.mkdirs();
        }
        // 上传
        File uploadFile=new File(newFile, file.getOriginalFilename());
        file.transferTo(uploadFile);

        InputStream inputStream=new FileInputStream(uploadFile);
        System.out.println(">>>>>>>>>>>>>>读取到List里面");
        //同步进行读取数据,会放置在内存里面.
        List<User> userList=EasyExcel.read(inputStream).head(User.class).
                sheet(0).doReadSync();
        for(User user:userList){
            System.out.println(">>>读取记录:"+user);
        }
        String uploadPath=realPath+"/"+file.getOriginalFilename();
        return "上传文件成功,地址为:"+uploadPath;
    }

image-20211108205400386

将文件进行上传, 控制台打印输出

image-20211108205430753

四.四 Excel 文件下载

 /**
     * 下载Excel文件
     * @date 2021/11/4 21:12
     * @author zk_yjl
     * @return
     */
    @GetMapping("/downloadExcel")
    @ResponseBody
    public void downloadExcel(HttpServletResponse response,String name) throws IOException {
        //1. 通过传入的参数,和相关的业务代码逻辑处理,获取相应的数据.
        //2. 将数据进行转换,转换成 List<User> 的形式.
        List<User> dataList=createDataList(name);
        //将数据进行下载.
        // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("员工表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream(), User.class).autoCloseStream(Boolean.FALSE).sheet("员工")
                    .doWrite(dataList);
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            JSONObject jsonObject=new JSONObject();;
            response.getWriter().println(jsonObject.toString());
        }

    }

    private List<User> createDataList(String name) {
        List<User> result=new ArrayList<>();
        for(int i=1;i<=10;i++){
          User user=new User();
          user.setId(i);
          user.setName(name+"_"+i);
          user.setSex(i%2==0?"女":"男");
          user.setAge(20+i);
          user.setDescription("我是第"+i+"个,我的名字是:"+user.getName());
          result.add(user);
        }
        return result;
    }

image-20211108205611413

点击后,进行下载

image-20211108205645899

image-20211108205712245

上传和下载文件均是成功的.

本章节的代码放置在 github 上:

https://github.com/yuejianli/springboot/tree/develop/SpringBoot_File

谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-11-09 19:20:29  更:2021-11-09 19:22:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:23:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码