channelsftp 上传文件为空_SpringBoot文件上传下载篇(九)

6bb51d000f34cbf17fc1fd75f51238a8.gif

点击上方蓝色字体,关注我们

a25fce33989cd07c57eb1c217c3de652.png

上传文件是互联网中应用的场景之一,最典型的情况就是上传头像。文件上传主要是将文件通过IO流传输到服务器的某一个特定的文件夹下。

f93680872dc75de4db16e67b24bf24ac.pngWhy->MultipartFile?

解析源码:

public interface MultipartFile extends InputStreamSource {

}
public class MockMultipartFile extends Object implements MultipartFile implements MultipartFile, Serializable {

}
public class CommonsMultipartFile implements MultipartFile, Serializable {

}
public interface MultipartFile extends InputStreamSource {

}

通过源码可以看出 MultipartFile是一个接口,这个接口的实现类有 CommonsMultipartFile,MockMultipartFileMultipartFile继承InputStreamSource这个接口。

MultipartFile
--String getName() //返回表单中file文件参数name的名称。
--String getOriginalFilename() // 文件原名称
--String getContentType() //返回文件的内容类型。
--boolean isEmpty() // 返回上传的文件是否为空,即,在多部分表单中没有选择任何文件,或者所选文件没有内容。
--long getSize() // 以字节为单位返回文件的大小。
--byte[] getBytes() //将文件的内容作为字节数组返回。
--InputStream getInputStream() //返回一个InputStream以从中读取文件的内容。
--void transferTo(File dest) //将收到的文件传输到给定的目标文件。

参考官网地址

https://docs.spring.io/spring/docs/current/javadoc-

api/org/springframework/web/multipart/MultipartFile.html

f93680872dc75de4db16e67b24bf24ac.png开始搭建

环境jdk1.8,引入了spring-boot-starter-thymeleaf做页面模板引擎。

 <properties>
    <java.version>1.8java.version>
properties>
<dependencies>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-devtoolsartifactId>
    <optional>trueoptional>
dependency>
dependencies>

application.properties配置文件

#thymeleaf
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
# 禁用 thymeleaf 缓存
spring.thymeleaf.cache=false

# 上传文件总的最大值
spring.servlet.multipart.max-request-size=10MB
# 单个文件的最大值
spring.servlet.multipart.max-file-size=10MB
# 是否支持批量上传   (默认值 true)
spring.servlet.multipart.enabled=true
# 上传文件的临时目录 (一般情况下不用特意修改)
spring.servlet.multipart.location=
# 文件大小阈值,当大于这个阈值时将写入到磁盘,否则存在内存中,(默认值0 一般情况下不用特意修改)
spring.servlet.multipart.file-size-threshold=0
# 判断是否要延迟解析文件(相当于懒加载,一般情况下不用特意修改)
spring.servlet.multipart.resolve-lazily=false

常见问题:

1、表单method设置为post,并将enctype设置为multipart/form-data。

2、html中name值要和@RequestParam("file")中的值保持一致。

3、上传文件大小spring.http.multipart.max-file-size限制,如果上传的文件超过设置的值会出现这个错误。

d48922c9a85c6583f33c3f6860602bda.png

这个错误是因为Spring文件上传重置问题,这个异常是捕获不到,需要Tomcat的默认连接器 maxSwallowSize 的参数。

<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"maxSwallowSize="-1" />

并在上传前实现Javascript检查文件大小。

单文件上传

单文件上传html页面

html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>单文件上传title>
head>
 <body>
 <p>单文件上传p>
<form method="POST" enctype="multipart/form-data" action="/upload" >
文件:<input type="file" name="file"/>
      <input type="submit"/>
form>
<hr/>
body>

创建FileUploadController中的upload方法 (单文件上传)

@PostMapping("/upload")
@ResponseBody
public String upload(@RequestParam("file") MultipartFile file) {
    //判断非空
    if (file.isEmpty()) {
        return "上传的文件不能为空";
    }
    try {
        // 测试MultipartFile接口的各个方法
        logger.info("[文件类型ContentType] - [{}]",file.getContentType());
        logger.info("[文件组件名称Name] - [{}]",file.getName());
        logger.info("[文件原名称OriginalFileName] - [{}]",file.getOriginalFilename());
        logger.info("[文件大小] - [{}]",file.getSize());
        logger.info(this.getClass().getName()+"图片路径:"+path);
        File f = new File(path);
        // 如果不存在该路径就创建
        if (!f.exists()) {
            f.mkdir();
        }
        File dir = new File(path + file.getOriginalFilename());
        // 文件写入
        file.transferTo(dir);
        return "上传单个文件成功";
    } catch (Exception e) {
        e.printStackTrace();
        return "上传单个文件失败";
    }
}

注:这里除了transferTo方法,也可以用字节流的方式上传文件,但是字节流比较慢,所以还是建议用transferTo,下面这个方法是封装的一个用字节流写入文件的方法。

  public void writeFile(MultipartFile file) {
    try {
        //获取输出流
        OutputStream os = new FileOutputStream(path + file.getOriginalFilename());
        //获取输入流 CommonsMultipartFile 中可以直接得到文件的流
        InputStream is = file.getInputStream();
        byte[] buffer = new byte[1024];
        //判断输入流中的数据是否已经读完的标识
        int length = 0;
        //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
        while((length = is.read(buffer))!=-1){
            //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
            os.write(buffer, 0, length);
        }
        os.flush();
        os.close();
        is.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

操作步骤

f724c5765d49bfcef0c44f73bc6862a2.gif

单文件上传完成啦,接下来就是多文件上传和文件下载。

1acb83d777dcb03e3d24aa3eb56ef649.png

多文件上传

html页面

html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多文件上传title>
head>
<body>
<p>多文件上传p>
<form method="POST" enctype="multipart/form-data" action="/uploadBatch">
    <p>文件1:<input type="file" name="file"/>p>
    <p>文件2:<input type="file" name="file"/>p>
    <p><input type="submit" value="上传"/>p>
form>
body>
html>

uploadBatch方法

@PostMapping("/uploadBatch")
@ResponseBody
public String uploadBatch(@RequestParam("files") MultipartFile[] files) {
    logger.info("文件名称:"+ files );
    if(files!=null&&files.length>0){
        String filePath = "D:\\datafile\\";
        for (MultipartFile mf : files) {
            // 获取文件名称
            String fileName = mf.getOriginalFilename();
            // 获取文件后缀
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            // 重新生成文件名
            fileName = UUID.randomUUID()+suffixName;

            if (mf.isEmpty()) {
                return "文件名称:"+ fileName +"上传失败,原因是文件为空!";
            }
            File dir = new File(filePath + fileName);
            try {
                // 写入文件
                mf.transferTo(dir);
                logger.info("文件名称:"+ fileName +"上传成功");
            } catch (IOException e) {
                logger.error(e.toString(), e);
                return "文件名称:"+ fileName +"上传失败";
            }
        }
        return "多文件上传成功";
    }
    return "上传文件不能为空";
}

操作步骤

fe1d9653b6572401cac363c0fcdc2862.gif

常见问题

 The field file exceeds its maximum permitted size of 1048576 bytes.

这个错误是由于springboot默认的文件大小是1MB造成的,当上传文件超过1MB时就会报错。解决这个报错可以在application.properties中设置上传参数,参数项是默认的,我们设置最大上传文件大小不超过10MB,再次上传会成功。

文件下载方法

@GetMapping("/downloadfile")
@ResponseBody
public String downloadFile(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
    String fileName = "大话设计模式(带目录完整版).pdf";// 文件名

    if (fileName != null) {
        //设置文件路径
        File file = new File("D:\\datafile\\大话设计模式(带目录完整版).pdf");
        //File file = new File(realPath , fileName);
        if (file.exists()) {
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment; fileName="+  fileName +";filename*=utf-8''"+ URLEncoder.encode(fileName,"UTF-8"));
            byte[] buffer = new byte[1024];
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                OutputStream os = response.getOutputStream();
                int i = bis.read(buffer);
                logger.info(""+i);
                while (i != -1) {
                    os.write(buffer, 0, i);
                    i = bis.read(buffer);
                }
                return "下载成功";
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    return "文件不存在";
}

在下载文件时,中文文件名称会出现乱码问题,需要设置一下即可。

response.setHeader("Content-Disposition", "attachment; fileName="+  fileName +";filename*=utf-8''"+ URLEncoder.encode(fileName,"UTF-8"));
f93680872dc75de4db16e67b24bf24ac.png总结

下载的html页面我就不复制啦,一个Spring Boot 上传和下载文件的简单 Demo 就完成了,感兴趣的同学可以将示例代码下载下来试试吧。

GitHub:

https://github.com/xiaonongOne/springboot-upload

a8dc01476ee28e2c5df5166e8a50ac57.png4a6724c3106c7d1debce1d79b44acc28.pnge5ef71d743c0f38b081dd30aec2b7e4e.png4a6724c3106c7d1debce1d79b44acc28.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505276.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

excel 科学计数法转换成文本完整显示_表格技巧—Excel里身份证号码显示不全的多种解决办法...

运用Excel表格可以快速统计和汇总数据&#xff0c;那么当在表格当中输入身份证号码时&#xff0c;表格通常显示不完全&#xff0c;这是为什么呢&#xff0c;今天小编就来给大家详细介绍当身份证号码显示不全时的多种解决办法&#xff0c;一起来学习一下吧。首先&#xff0c;我们…

nginx header参数丢失_某Nginx后门分析与重现

安全分析与研究专注于全球恶意软件的分析与研究背景前几天&#xff0c;接到一个nginx后门样本&#xff0c;本着就分析和复现的思路&#xff0c;完整的将整个过程做一次复现&#xff0c;不料最终还获取到了后门的核心代码部分&#xff0c;遂将其整理发布&#xff0c;仅供学习研究…

virtual box一直正在加载文件_Linux基础导航与文件管理

Linux基础导航与文件管理对于新手&#xff0c;或许很关心如何通过命令行来控制操作系统。这编文章将会尝试带你快速熟悉Linux系统基础&#xff0c;但是不会覆盖所有的Linux系统知识&#xff0c;在未来对Linux探索过程中会有很大的帮助。本篇文章继续学习Linux基础。准备与目标在…

打开fiddler后打不开网页_如何通过fiddler的导入导出功能,保存一份分类管理的请求报文...

在使用fiddler抓取请求报文时&#xff0c;我们更习惯于直接操作APP或者web系统&#xff0c;然后到fiddler中找我们想要的数据报文。但若这些报文是我们经常要看的 &#xff0c;我们可以使用另外一种更简单的方式来查看&#xff0c;那就是把我们想要的报文保存到本地&#xff0c…

和vc的正确服用时间_最新研究:口服VC吸收远高于我们的意料

本文采自美国著名科普杂志&#xff0c;Townsendletter&#xff0c;发抗坏血酸口服生物利用中意外的早期反应。本研究提示&#xff0c;口服VC可能达到与静脉VC相同或接近的血液VC水平&#xff0c;而且纯VC比VC钠盐吸收更好。这是前所未料的。-成长博士。 介绍&#xff1a;重复和…

定点运算和浮点运算_C2000浮点运算注意事项——CPU和CLA的差异及误差处理技巧...

C28xFPU架构的C2000微处理器在原有的C28x定点CPU的基础上加入了一些寄存器和指令&#xff0c;来支持IEEE 单精度浮点数的运算。对于在定点微处理器上编写的程序&#xff0c;浮点C2000也完全兼容&#xff0c;不需要对程序做出改动。浮点处理器相对于定点处理器有如下好处&#x…

imread函数 matlab_地理人,你会用Matlab吗?

​Matlab 读取不同格式数据作为一个地信的小白&#xff0c;本科就学会了一个ArcGIS。虽然Matlab, C, Java, C, C# 等的编程课上了一大堆&#xff0c;但是考完试就完全忘了&#xff0c;妥妥的一个代码小白&#xff0c;当初连如何切换当前目录都不会……读研后&#xff0c;发现Ma…

url过滤怎么解除_腾讯面试官是这样来问布隆过滤器的?

作者&#xff1a;张振伟来源&#xff1a;https://zhangzw.com/20190521.html假设遇到这样一个问题&#xff1a;一个网站有 20 亿 url 存在一个黑名单中&#xff0c;这个黑名单要怎么存&#xff1f;若此时随便输入一个 url&#xff0c;你如何快速判断该 url 是否在这个黑名单中&…

mysql数值比中文检索快_MySQL 千万 级数据量根据(索引)优化 查询 速度

一、索引的作用索引通俗来讲就相当于书的目录&#xff0c;当我们根据条件查询的时候&#xff0c;没有索引&#xff0c;便需要全表扫描&#xff0c;数据量少还可以&#xff0c;一旦数据量超过百万甚至千万&#xff0c;一条查询sql执行往往需要几十秒甚至更多&#xff0c;5秒以上…

mysql5.7.24 安装步骤_MySQL5.7.24解压版安装步骤

网上安装MySQL数据库的教程有.msi格式包安装和.zip格式解压安装&#xff0c;zip安装我个人感觉安装方式纯净又能学习更多知识&#xff0c;因此我更倾向于zip安装。一、下载并解压前往MySQL官网下载5.7.24版本https://dev.mysql.com/downloads/下拉移动看见select Version 选择m…

mysql utf8mb4 造成慢_mysql使用utf8mb4经验吐血总结

1. utf8 与 utf8mb4 异同1234The character set named utf8 uses a maximum of three bytes per character and contains only BMP characters. The utf8mb4 character set uses a maximum of four bytes per character supports supplementary characters:- For a BMP charact…

java移动接口发短信_Java面试零碎知识点

1.Java文件经过JVM编译成字节码文件&#xff0c;即.class文件&#xff0c;将字节码文件在不同的操作系统中运行时&#xff0c;操作系统再将字节码文件编译成机器码文件。这就是Java跨平台2.首先明确一点&#xff0c;java 的 GC 回收是完全自动的&#xff0c;没有提供相关 api 手…

java重定向代码_Java程序员经典面试题集大全 (三十四)

341. Servlet API中forward() 与redirect()的区别&#xff1f;答&#xff1a;为实现程序的模块化&#xff0c;就需要保证在不同的Servlet之间可以相互跳转&#xff0c;而Servlet中主要有两种实现跳转的方式&#xff1a;FORWARD方式与redirect方式。 Forward() : 是服务器内部的…

mysql用户阻塞数_MySQL实例阻塞分析一例(线程statistics状态)

本文用实例来分析MySQL阻塞—线程statistics状态。一、 现象某日下午下班后低峰期&#xff0c;现网MySQL一个库突然报出大量慢sql&#xff0c;状态是 statistics&#xff0c;但是过后拿这些sql去执行的时候&#xff0c;实际很快。处于 statistics 状态的线程有个特征&#xff1…

无法获取未定义或 null 引用的属性“text”_【CSS】是时候开始用 CSS 自定义属性了...

自定义属性(有时候也被称作CSS变量或者级联变量)是由CSS作者定义的&#xff0c;它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如&#xff1a;--main-color: black;)&#xff0c;由var() 函数来获取值(比如&#xff1a;color: var(--main-color);)复杂的网站都…

斐波那契数列不用数组_兔子数列——斐波那契数列

相信人们都对斐波那契数列有或多或少的了解&#xff0c;如果没有&#xff0c;那你一定听过黄金分割比或是见过下面这种图片&#xff1a;斐波那契生活在十三世纪的意大利&#xff0c;原名列奥纳多皮萨诺(Leonardo Pisano)&#xff0c;他出生在意大利那个后来因为伽里略做过自由落…

sqlserver服务启动失败_条码打印软件连接SQL数据库出现TCP连接失败解决办法

小编今天用条码打印软件连接SQL 数据库遇到了一个问题&#xff1a;通过端口1433连接到主机localhost的TCP/IP连接失败。错误&#xff1a;“Connection refused&#xff1a;connect。请验证连接属性。确保SQL Server的实例正在主机上运行&#xff0c;且在此端口接收TCP/IP连接&a…

mysql57win10安装配置_Win10 OS安装(配置)MySQL 5.7(解压版)

Win10 OS安装(配置)MySQL 5.7(解压版)下载及解压文件名&#xff1a;mysql-5.7.27-win32.zipzip是解压版&#xff0c;msi是安装版&#xff0c;本教程仅说明zip格式的配置方法。解压(假设解压后根路径为D:\ide\mysql-5.7.27-win32)相关截图添加环境系统变量path 增加D:\ide\mysql…

pep8 python 编码规范_如何用好python编码规范,写一手漂亮的代码

前一段时间在编写python 代码的时候编辑器中一直在提示规范问题&#xff0c;因为强迫症的原因&#xff0c;我决定遵循python 的编码规范去编码&#xff0c;然后把需要注意的点记录下来&#xff0c; 帮助自己和大家一起成长。这是我的main.py文件中的一部分代码&#xff0c;经过…

mysql约束_Mysql约束条件

约束条件1约束条件约束是一种限制&#xff0c;通过对表中的数据做出限制&#xff0c;来确保表中数据的完整性&#xff0c;唯一性默认约束CREATE TABLE tb(id INT DEFAULT a ,name VARCHAR(20));插入数据的时候&#xff0c;如果没有明确为字段赋值&#xff0c;则自动赋予默认值在…