Springboot实现文件上传模块知识点
流
- “流”是一个抽象的概念,它是对输入输出设备的一种抽象理解,在java中,对数据的输入输出操作都是以“流”的方式进行的。
- “流”具有方向性,输入流、输出流是相对的。当程序需要从数据源中读入数据的时候就会开启一个输入流,相反,写出数据到某个数据源目的地的时候也会开启一个输出流。
- 数据源可以是文件、内存或者网络等。
MultipartFile工具类
MultipartFile是SpringMVC提供简化上传操作的工具类。
在不使用框架之前,都是使用原生的HttpServletRequest来接收上传的数据,文件是以二进制流传递到后端的,然后需要我们自己转换为File类。使用了MultipartFile工具类之后,我们对文件上传的操作就简便许多了。
package org.springframework.web.multipart;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import org.springframework.core.io.InputStreamSource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.util.FileCopyUtils;
public interface MultipartFile extends InputStreamSource {
//getName() 返回参数的名称
String getName();
//获取源文件的昵称
@Nullable
String getOriginalFilename();
//getContentType() 返回文件的内容类型
@Nullable
String getContentType();
//isEmpty() 判断是否为空,或者上传的文件是否有内容
boolean isEmpty();
//getSize() 返回文件大小 以字节为单位
long getSize();
//getBytes() 将文件内容转化成一个byte[] 返回
byte[] getBytes() throws IOException;
//getInputStream() 返回InputStream读取文件的内容
InputStream getInputStream() throws IOException;
default Resource getResource() {
return new MultipartFileResource(this);
}
//transferTo(File dest) 用来把 MultipartFile 转换换成 File
void transferTo(File var1) throws IOException, IllegalStateException;
default void transferTo(Path dest) throws IOException, IllegalStateException {
FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
}
}
HttpServletRequest类
每次只要有请求进入 Tomcat 服务器,Tomcat 服务器就会把请求过来的 HTTP 协议信息解析好封装到 Request 对象中。然后传递到 service 方法(doGet 和 doPost)中给我们使用。我们可以通过 HttpServletRequest 对象,获取到所有请求的信息。
File类
构造方法
//以pathname为路径创建File对象
File f = new File("文件路径")
//根据一个父File对象和子文件路径创建File对象
File f = new File("parent","child")
创建文件
//在工作空间目录下创建a.txt的文件
File f = new File("a.txt");
f.createNewFile();
在G:\路径下创建一个a.txt的文件.如果已经有的话这不会重新创建
File f = new File("G:\\a.txt");
f.createNewFile();
如果路径写成\\a.txt,会在盘符下创建新的文件
File f = new File("\\a.txt");
f.createNewFile();
创建文件夹
//在工作空间目录下创建a.txt的文件夹
File f = new File("a");
f.mkdir();
在G:\路径下创建一个a.txt的文件夹.如果已经有的话这不会重新创建
File f = new File("G:\\a");
f.mkdir();
如果路径写成\\a.txt,会在盘符下创建新的文件夹
File f = new File("\\a");
f.mkdir();
在g盘下创建文件夹a,a 下创建一个b文件夹
File f = new File("G:\\a\\b");
f.mkdirs(); //注意mkdirs(),创建多个文件夹
常用方法
f.delete(); //删除file
f.exists(); //file是否存在
f.getName(); //得到file名字
f.isDirectory(); //file是否是文件夹
f.isFile(); //file是否是文件
f.length(); //file的长度
Hutool——FileUtil工具
状态码400原因
通常的原因:
前端提交的字段名称或者字段类型和后台的实体类不一样,或者前端提交的参数跟后台需要的参数个数不一致,导致无法封装。比如在SprimgMVC的控制器方法中使用了@RequestParam修饰了一个yanggb参数,但是前端在请求的时候并没有带上yanggb参数或yanggb参数为空值,就会出现这种情况;再比如前端提交到后台的数据应该是JSON字符串类型,而前端没有将对象转化为字符串类型,也会返回HTTP请求状态码400。
解决方法:
对照字段名称,类型保证一致。
@RequestParam(“image”)
@RequestParam
,这个注解使用时候最好添加参数(value),当然发送请求的地方也要按照这个value来起名
基础代码
@RequestMapping("/uploadImage") //HttpServletRequest、MultipartFile
public BaseResponse<FileUploadOutput> uploadImage(@RequestParam("image") MultipartFile uploadFile, HttpServletRequest request) throws IOException {
//使用MultipartFile类的方法获取上传文件的原始名称
String originalFilename = uploadFile.getOriginalFilename();
//通过hutool的extName方法,传入上传文件的原始名称,获取文件类型
String type = FileUtil.extName(originalFilename);
//使用MultipartFile类的方法获取上传文件的大小
long size = uploadFile.getSize();
//利用hutool的IdUtil,快速生成随机的uuid
String uuid = IdUtil.fastSimpleUUID();
//uuid加上文件的类型type,使用到了hutool的StrUtil,生成"."
String fileUUid = uuid + StrUtil.DOT + type;
//对上传的文件重命名,避免文件重名,以pathname+fildUUid为路径创建File对象
File newuploadFile = new File(ImgsPath + fileUUid);
//判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
File parentFile = newuploadFile.getParentFile(); //获取上一节的File对象
if(!parentFile.exists()) {
parentFile.mkdirs();
}
//把上传获得的文件存储到磁盘目录
uploadFile.transferTo(newuploadFile);
//生成访问的url
String url = "http://localhost:9090/" + fileUUid;
//存储数据库
//封装并返回FileUploadOutput对象
return BaseResponse.success(FileUploadOutput.of(url));
}