一、单文件上传
1.1MultipartFile
MultipartFile 是 Spring 框架中的一个接口,主要用于处理 HTTP 请求中的文件上传。它提供了一些方法来获取上传文件的信息和内容。 以下是 MultipartFile 的一些主要方法:
- getOriginalFilename():返回上传文件的原始文件名。
- getName():返回表单中文件组件的名字。
- getContentType():返回文件的 MIME 类型。
- isEmpty():返回文件是否为空。
- getSize():返回文件的大小,单位为字节。
- getBytes():返回文件的内容,作为字节数组。
- getInputStream():返回一个 InputStream,用于读取文件的内容。
- transferTo(File dest):将上传的文件保存到目标文件中。
@PostMapping("/upload") // 定义一个处理文件上传的POST请求映射
public String handleFileUpload(@RequestParam("file") MultipartFile file) { // 接收名为"file"的文件参数
String name = file.getOriginalFilename(); // 获取原始文件名
try {
file.transferTo(new File("/path/to/destination/" + name)); // 将文件保存到指定路径
return "File uploaded successfully"; // 返回文件上传成功的提示信息
} catch (IOException e) {
e.printStackTrace(); // 打印异常堆栈信息
return "Failed to upload file"; // 返回文件上传失败的提示信息
}
}
File.separator 是系统相关的默认名称分隔符。在 UNIX 系统中,这个字段的值为 '/';在 Microsoft Windows 系统中,它为 '\'。
private static final String ROOT_PATH = System.getProperty("user.dir") + File.separator + "files";
System.getProperty("user.dir") 是 Java 系统属性,用于获取用户的当前工作目录。这通常是运行 JVM 的路径。
1.2MIME 类型
MIME 类型是一种标准,用于表示文档、文件或字节流的性质和格式。 以下是一些常见的 MIME 类型:
- text/plain:纯文本文件
- text/html:HTML 文件
- text/css:CSS 文件
- text/javascript:JavaScript 文件
- image/jpeg:JPEG 图像文件
- image/png:PNG 图像文件
- image/gif:GIF 图像文件
- application/pdf:PDF 文件
- application/msword:Microsoft Word 文件
- application/vnd.ms-excel:Microsoft Excel 文件
- application/vnd.ms-powerpoint:Microsoft PowerPoint 文件
- application/json:JSON 数据
- application/xml:XML 数据
- application/zip:ZIP 压缩文件
这些只是一些常见的 MIME 类型,实际上 MIME 类型的数量非常多,可以表示各种各样的文件和数据格式。
1.3Hutool插件
概述
Hutool是一个功能丰富的Java工具类库,它旨在简化Java开发中的常见任务。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
</dependency>
Hutool提供了一系列的工具类和组件,具体如下:
- 文件操作:对文件的读写、复制、删除等进行封装,简化了文件处理流程。
- 流操作:对输入输出流的包装,使得流的处理更加便捷。
- 加密解密:提供多种加密解密算法的实现,如MD5、SHA等。
- 转码:支持字符串与字节数组之间的转换,以及不同编码格式之间的转换。
- 正则表达式:简化了正则表达式的使用,提供匹配和替换等功能。
- 线程操作:包括线程池管理、线程控制等。
- XML处理:简化了XML文档的解析、生成和查询。
- 缓存:提供简单的缓存机制,帮助提升程序性能。
- 定时任务:支持类似Crontab表达式的定时任务调度。
- 数据库操作:基于JDBC的封装,简化了数据库操作。
- 布隆过滤器:实现布隆过滤算法,用于高效判断一个元素是否属于某个集合。
- 切面编程:即使在非IOC环境下,也支持AOP编程。
- 多关键字查找:基于DFA模型的多关键字搜索实现。
Hutool的设计哲学是“小而全”,通过静态方法封装常用的功能,降低API的学习成本,提高开发效率,使Java代码更加优雅。它是Java项目中“util”包的良好替代品,可以节省开发人员在公用类和工具方法上的时间,让开发者更专注于业务逻辑。
FileUtil 类
FileUtil 是 Hutool 工具包中的一个类,主要用于文件和目录的操作。它提供了一系列的静态方法,可以方便地进行文件的创建、复制、删除、移动、读取和写入等操作。
String originalFilename = file.getOriginalFilename(); // 文件的原始名称
String mainName = FileUtil.mainName(originalFilename); // 获取文件主名称
String extName = FileUtil.extName(originalFilename); // 获取文件扩展名
在 FileController 类的 upload 方法中,上述使用了 FileUtil 的 mainName 和 extName 方法来获取上传文件的主名称和扩展名:
以下是 FileUtil 的一些主要方法:
- file(String path):根据文件路径创建 File 对象。
- mkdir(String path):创建目录,如果父目录不存在,会一并创建。
- copy(File src, File dest, boolean isOverride):复制文件或目录,通过第三个参数控制如果目标文件存在时是否覆盖。
- move(File src, File dest, boolean isOverride):移动文件或目录,通过第三个参数控制如果目标文件存在时是否覆盖。
- del(File file):删除文件或目录。
- readUtf8String(File file):读取文件内容,返回 UTF-8 编码的字符串。
- writeUtf8String(String content, File file):将字符串写入文件,编码为 UTF-8。
- getAbsolutePath(File file):获取文件的绝对路径。
- getName(File file):获取文件名或目录名。
- getExtension(File file):获取文件的扩展名。
- getSize(File file):获取文件或目录的大小。
这些只是 FileUtil 类的一部分方法,实际上它还提供了更多的方法,可以满足各种复杂的文件操作需求。
1.4实现
@Value("${ip:localhost}")
String ip;
@Value("${server.port:8083}")
String port;
private static final String ROOT_PATH = System.getProperty("user.dir") + File.separator + "files";
@PostMapping("/upload")
public Result upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return Result.error("上传文件不能为空");
}
String originalFilename = file.getOriginalFilename(); // 文件的原始名称
// aaa.png
String mainName = FileUtil.mainName(originalFilename); // 获取文件主名称aaa
String extName = FileUtil.extName(originalFilename); // 获取文件扩展名png
System.out.println("文件的原始名称:" + originalFilename);
System.out.println("文件的主名称:" + mainName);
try {
if (!FileUtil.exist(ROOT_PATH)) {
FileUtil.mkdir(ROOT_PATH); // 如果当前文件的父级目录不存在,就创建
}
if (FileUtil.exist(ROOT_PATH + File.separator + originalFilename)) { // 如果当前上传的文件已经存在了,那么这个时候我就要重名一个文件名称
originalFilename = System.currentTimeMillis() + "_" + mainName + "." + extName;
}
File saveFile = new File(ROOT_PATH + File.separator + originalFilename);
System.out.println("文件的保存路径:" + saveFile.getAbsolutePath());
file.transferTo(saveFile); // 存储文件到本地的磁盘里面去
String url = "http://" + ip + ":" + port + "/file/download/" + originalFilename;
return Result.success(url); //返回文件的链接,这个链接就是文件的下载地址,这个下载地址就是我的后台提供出来的
//另外一种思路
// file.transferTo(new File(UPLOAD_DIR + fileName));
// // 返回文件的下载链接
// String fileDownloadUri = "/file/download?fileName=" + fileName;
// return javax.xml.transform.Result.success(fileDownloadUri);
} catch (IOException e) {
e.printStackTrace();
return Result.error("上传文件失败");
}
}
测试
二、文件下载
2.1URLEncoder
URLEncoder 是 Java 中的一个工具类,用于将字符串转换为 application/x-www-form-urlencoded MIME 格式。这种格式通常用于 HTTP 请求的查询字符串部分。
以下是 `URLEncoder` 的一些常用方法:
1. `encode(String s, String enc)`: 这个方法用于将指定的字符串按照指定的编码方式进行转码。例如,`URLEncoder.encode("hello world", "UTF-8")` 将返回 "hello+world"。
2. `encode(String s)`: 这个方法已经被废弃,因为它使用平台默认的编码方式进行转码,这可能会导致不可预知的结果。建议使用 `encode(String s, String enc)` 方法。
以下是 `URLEncoder.encode(String s, String enc)` 方法的一个示例:
try { String original = "文件名 with spaces"; String encoded = URLEncoder.encode(original, "UTF-8"); System.out.println(encoded); // 输出 "文件名+with+spaces" } catch (UnsupportedEncodingException e) { e.printStackTrace(); }
在这个示例中,空格被转换为 `+`。如果原始字符串中包含非 ASCII 字符或其他需要编码的字符,它们将被转换为 `%` 后跟两个十六进制数字的形式。
2.2实现
@GetMapping("/download/{fileName}")
public Result download(@PathVariable("fileName") String fileName, HttpServletResponse response) throws IOException {
// response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileFullName, "UTF-8")); // 附件下载
String filePath = ROOT_PATH + File.separator + fileName;
if (!FileUtil.exist(filePath)) {
return Result.error("文件不存在");
}
byte[] bytes = FileUtil.readBytes(filePath);
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(bytes); // 数组是一个字节数组,也就是文件的字节流数组
outputStream.flush();
outputStream.close();
System.out.println("文件下载成功");
return Result.success();
}
2.3配置介绍
在 Spring Boot 中,你可以在 application.properties 或 application.yml 文件中配置文件上传的最大大小。这是通过设置 spring.servlet.multipart.max-file-size 和 spring.servlet.multipart.max-request-size 属性来实现的。
- spring.servlet.multipart.max-file-size:设置单个文件的最大大小。如果上传的文件超过这个大小,将会抛出异常。
- spring.servlet.multipart.max-request-size:设置整个请求的最大大小。这包括所有的文件和其他表单数据。如果整个请求的大小超过这个值,将会抛出异常。
- spring.servlet.multipart.file-size-threshold:这个属性用于设置写入磁盘的文件的大小阈值。如果上传的文件大小超过这个阈值,那么文件将会被写入到磁盘,而不是保存在内存中。这可以防止大文件上传消耗过多的内存。
- spring.servlet.multipart.location:这个属性用于设置临时文件的存储位置。当文件大小超过 file-size-threshold 时,文件将会被写入到这个位置。
servlet:
multipart:
max-file-size:20MB
max-request-size:20MB
2.4文件预览
根据文件的类型区分的,一般是图片和 pdf 可以预览
response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(fileFullName, "UTF-8")); // 预览
Content-Disposition 是 HTTP 响应头部的一个字段,它定义了获取的资源如何处理。这个字段通常用于下载操作,告诉浏览器如何处理响应的内容。 Content-Disposition 主要有两个值:
- inline:这意味着资源应该直接在浏览器中显示,如果可能的话。例如,如果资源是一个图像或 PDF 文档,大多数浏览器都能够直接在浏览器窗口中显示这些类型的文件。
- attachment:这意味着资源应该被下载和保存到本地,而不是直接在浏览器中显示。
Content-Disposition 还可以包含一个 filename 参数,这个参数可以指定一个默认的文件名,当用户保存资源时,浏览器会使用这个文件名。 例如,Content-Disposition: attachment; filename="filename.jpg" 这个头部会告诉浏览器下载资源并将其保存为 "filename.jpg"。