SpringBoot 中的文件上传下载
前题
基于:IntelliJ IDEA
、Maven构建工具
、JDK1.8
、SpringBoot 2.3.4
编写。
官人如需使用 Maven 请阅读教程:Maven 构建工具的下载与安装
官人如需使用 IDEA 请阅读教程:IntelliJ IDEA
更多干货
请参考:Java学习资料
定义
文件上传和下载是JAVA WEB中常见的一种操作,文件上传主要是将文件通过IO流传输到服务器的某一个特定的文件夹下;
使用
pom.xml 依赖
在pom.xml中添加上spring-boot-starter-web
和spring-boot-starter-thymeleaf
的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>io</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>io</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<!--thymeleaf模板引擎-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--test-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties配置文件
默认情况下Spring Boot无需做任何配置也能实现文件上传的功能
# 关闭 thymeleaf 缓存
spring.thymeleaf.cache=false
# 是否支持批量上传 (默认值 true)
spring.servlet.multipart.enabled=true
# 上传文件的临时目录 (一般情况下不用特意修改)
spring.servlet.multipart.location=
# 上传文件最大为 1M (默认值 1M 根据自身业务自行控制即可)
spring.servlet.multipart.max-file-size=1048576
# 上传请求最大为 10M(默认值10M 根据自身业务自行控制即可)
spring.servlet.multipart.max-request-size=10485760
# 文件大小阈值,当大于这个阈值时将写入到磁盘,否则存在内存中,(默认值0 一般情况下不用特意修改)
spring.servlet.multipart.file-size-threshold=0
# 判断是否要延迟解析文件(相当于懒加载,一般情况下不用特意修改)
spring.servlet.multipart.resolve-lazily=false
编写controller层
实现 单文件上传
、 多文件上传
、 BASE64编码
三种上传方式。
@RequestParam("file")
此处的"file"
对应的就是html 中 name="file"
的 input 标签.
而将文件真正写入的还是借助的commons-io
中的FileUtils.copyInputStreamToFile(inputStream,file)
单文件上传: 访问/uploads/upload1
和/uploads/upload4
具体可结合index.html
多文件上传访问:/uploads/upload2
BASE64编码上传访问:/uploads/upload3
都可在控制台查看日志输出。
package com.example.io.controller;
import org.apache.catalina.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.*;
@Controller
@RequestMapping("/uploads")
public class FilesUploadController {
private static final Logger log = LoggerFactory.getLogger(FilesUploadController.class);
//跳转到 index页面
@GetMapping
public String index(){
return "index";
}
@PostMapping("/upload1")
@ResponseBody
public Map<String,String> upload1(@RequestParam("file") MultipartFile file) throws IOException {
//控制台输出日志
log.info("[文件类型] - [{}]", file.getContentType());
log.info("[文件名称] - [{}]", file.getOriginalFilename());
log.info("[文件大小] - [{}]", file.getSize());
file.transferTo(new File("F:\\源码\\文件上传\\upload\\"+file.getOriginalFilename()));
Map<String,String> result=new HashMap<>();
result.put("contentType",file.getContentType());
result.put("filename",file.getOriginalFilename());
result.put("fileSize",file.getSize()+"");
return result;
}
//文件上传相关代码
@RequestMapping("/upload4")
@ResponseBody
public String upload(@RequestParam("test") MultipartFile file) {
if (file.isEmpty()) {
return "文件为空";
}
// 获取文件名
String fileName = file.getOriginalFilename();
log.info("上传的文件名为:" + fileName);
// 获取文件的后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
log.info("上传的后缀名为:" + suffixName);
// 文件上传后的路径
String filePath = "F:\\源码\\文件上传\\upload\\u1\\";
// 解决中文问题,linux下中文路径,图片显示问题
// fileName = UUID.randomUUID() + suffixName;
File dest = new File(filePath + fileName);
// 检测是否存在目录
if (!dest.getParentFile().exists()) {
dest.getParentFile().mkdirs();
}
try {
file.transferTo(dest);
return "上传成功";
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "上传失败";
}
@PostMapping("/upload2")
@ResponseBody
public List<Map<String, String>> upload2(@RequestParam("file") MultipartFile[] files) throws IOException {
if (files == null || files.length == 0) {
return null;
}
List<Map<String, String>> results = new ArrayList<>();
for (MultipartFile file : files) {
// TODO Spring Mvc 提供的写入方式
//file.getOriginalFilename 原始文件名
file.transferTo(new File("F:\\源码\\文件上传\\uploads\\" + file.getOriginalFilename()));
Map<String, String> map = new HashMap<>(16);
map.put("contentType", file.getContentType());
map.put("fileName", file.getOriginalFilename());
map.put("fileSize", file.getSize() + "");
results.add(map);
}
return results;
}
@PostMapping("/upload3")
@ResponseBody
public void upload2(String base64) throws IOException {
// TODO BASE64 方式的 格式和名字需要自己控制(如 png 图片编码后前缀就会是 data:image/png;base64,)
final File tempFile = new File("F:\\源码\\文件上传\\upload\\test.jpg");
// TODO 防止有的传了 data:image/png;base64, 有的没传的情况
String[] d = base64.split("base64,");
final byte[] bytes = Base64Utils.decodeFromString(d.length > 1 ? d[1] : d[0]);
FileCopyUtils.copy(bytes, tempFile);
}
}
编写index.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
</head>
<link rel="stylesheet" href="style.css">
<body>
<h2>单文件上传:</h2>
<div>
<form method="POST" enctype="multipart/form-data" action="/uploads/upload1">
<p>
文件1:<input type="file" name="file"/>
<input type="submit" value="上传"/>
</p>
</form>
</div>
<form action="/uploads/upload4" method="POST" enctype="multipart/form-data">
文件:<input type="file" name="test"/>
<input type="submit" />
</form>
<hr/>
<h2>多文件上传:</h2>
<div>
<form method="POST" enctype="multipart/form-data"
action="/uploads/upload2">
<p>
文件1:<input type="file" name="file"/>
</p>
<p>
文件2:<input type="file" name="file"/>
</p>
<p>
<input type="submit" value="上传"/>
</p>
</form>
</div>
<hr/>
<h2>Base64文件上传:</h2>
<div>
<form method="POST" action="/uploads/upload3">
<p>
BASE64编码:<textarea name="base64" rows="10" cols="80"></textarea>
<input type="submit" value="上传"/>
</p>
</form>
</div>
</body>
</html>
测试
点击启动类后访问http://localhost:8080/
单文件和多文件上传就不演示了下面是Base64文件上传的方式:
打开浏览器访问:http://base64.xpcha.com/pic.html
选择一张图片将其转换为base64编码
的,随后将转换后的base64字符串
内容复制
到下图中的文本框
中,点击上传即可,随后到指定目录下
就可以看到我们上传的文件了
总结
待完善…
本教程基于最新的spring-boot-starter-parent:2.3.4RELEASE
编写,目前很多大佬都写过关于SpringBoot的教程了,如有雷同,请多多包涵.