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;我们…

sublime运行python代码_怎么用sublime运行python

首先需要安装一个Sublime Text(http://www.sublimetext.com/)和一个Python(https://www.python.org/downloads/)接下来打开Sublime Text&#xff1a;1、如下图所示&#xff0c;点击菜单栏中的Tools —> Build System —> New Build System(系统默认选择的是Automatic&…

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

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

bch纠错码 码长8_浅析BCH码的编码方法.docx

浅析BCH码的编码方法浅析BCH码的编码方法0 引言数字信号在传输系统中传输时&#xff0c;不免会受到各种因素的干扰&#xff0c;使到达接收端的数字信号中混有噪声&#xff0c;从而引发错误判决。为了抗击传输过程中的干扰&#xff0c;必然要利用纠错码的差错控制技术。BCH码是纠…

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

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

高德地图各种摄像头图标_高德导航中,限速摄像头,违章摄像头,监控摄像头各有什么区别...

展开全部限速摄像头e69da5e6ba903231313335323631343130323136353331333365666163是测速用的&#xff0c;超过限制时速就会抓拍&#xff0c;一般都是两个点中间的距离固定&#xff0c;分别拍照进入分析系统记录&#xff0c;超出时速限制&#xff0c;就会记录违章了。违章摄像头…

go去掉最后一个字符_Go语言去除字符串中的指定字符

Go语言中常用的去除字符串中指定字符的方法如下表所示。 表:字符串处理函数 方法功能描述 func Trim(s string, cutset string) string 将字符串 s 首尾包含在 cutset 中的任一字符去掉返回 func TrimFunc(s string, f func(rune) bool) string 将字符串 s 首尾满足函数 f(r)=…

打开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…

python模拟登录吃鸡_Python高级爬虫开发,高难度JS解密教程,绝地求生模拟登陆!...

前言这篇文章因为涉及到JS解密部分&#xff0c;所以难度比较高&#xff0c;Python基础比较薄弱的同学可以来看看思路。开始进入到该网站后我们可以看到如下界面&#xff0c;今天要做的内容就是模拟登陆那么咱们首先抓到登陆的包看看&#xff1a;登陆的同时总共发送了两次post请…

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

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

jquery li ul 伪分页_求教关于Jquery的ul li的分页,该怎么处理

求教关于Jquery的ul li的分页ul 下有若干个li 3个为1个分页 1个input按钮点击显示后3个 另一个显示前3个 求大神这个怎么做分享到&#xff1a;更多------解决方案--------------------html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org…

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

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

python dataframe遍历_对Python中DataFrame按照行遍历的方法

对Python中DataFrame按照行遍历的方法在做分类模型时候&#xff0c;需要在DataFrame中按照行获取数据以便于进行训练和测试。import pandas as pddict[[1,2,3,4,5,6],[2,3,4,5,6,7],[3,4,5,6,7,8],[4,5,6,7,8,9],[5,6,7,8,9,10]]datapd.DataFrame(dict)print(data)for indexs i…

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

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

python enumerate函数_Python中enumerate函数用法详解

enumerate函数用于遍历序列中的元素以及它们的下标,多用于在for循环中得到计数,enumerate参数为可遍历的变量&#xff0c;如 字符串&#xff0c;列表等一般情况下对一个列表或数组既要遍历索引又要遍历元素时&#xff0c;会这样写&#xff1a;for i in range (0,len(list)):pri…

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…

python在工作中怎么用_如何用python在工作中“偷懒”

原标题&#xff1a;如何用python在工作中“偷懒”“偷懒还能干完活&#xff0c;才是本事 ”有些朋友在工作中会有这样的困惑&#xff1a;明明我从早忙到晚&#xff0c;为什么得到的评价还不高&#xff1f;要知道&#xff0c;企业对一个员工的评价是出于“ 产出”而非“ 付出”。…

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…