요구 사항:
지정된 폴더에 파일을 업로드하는 파일 업로드 함수를 작성하세요.
그런 다음 업로드가 성공한 후 파일이 에코됩니다.
★ Spring Boot는 파일 업로드에 대한 자동 구성 지원을 제공합니다.
Spring Boot的文件上传自动配置主要由 MultipartAutoConfiguration 和 MultipartProperties 两个类组成。
MultipartProperties负责加载 spring.servlet.multipart.* 开头的配置属性。
MultipartAutoConfiguration 则根据 MultipartProperties 读取的配置属性来初始化
StandardServletMultipartResolver 解析器对象。
MultipartAutoConfiguration: 파일 업로드를 처리하는 클래스입니다.
MultipartProperties : 구성 파일에서 spring.servlet.multipart.*로 시작하는 구성 속성을 읽는 데 사용되는 속성 처리 클래스입니다.
★ MultipartProperties 클래스에서 지원되는 파일 업로드 관련 구성 속성
# 设置每个文件上传域的最大大小
spring.servlet.multipart.max-file-size=10MB
# 设置整个请求支持的最大大小
spring.servlet.multipart.max-request-size=50MB
# 设置文件上传的中转目录
spring.servlet.multipart.location=d:/temp
★ 파일 업로드 단계
(1) 프런트 엔드 페이지의 파일 요청은 "multipart/form-data" 인코딩 방법으로 제출됩니다.
(2) MultipartFile 유형의 속성을 정의하여 파일 업로드 도메인을 캡슐화합니다.
(3) 업로드된 파일은 MultipartFile 속성을 통해 접근할 수 있으며, 해당 파일은 어떤 디렉터리(또는 데이터베이스)에도 쓸 수 있습니다.
▲ 파일 업로드 에코를 확인하시길 바랍니다
能看到上传后文件的图片,
(1)需要将服务器保存文件的所使用的文件名传回给视图页面。
(2)还需要将保存文件的路径设置为Spring Boot的静态资源路径。
添加额外的静态资源路径时,额外添加的磁盘最后必须要有一个斜杠结尾
파일 업로드: 코드 데모:
파일 업로드 페이지를 더 보기 좋게 만들려면 이러한 파일 업로드 컨트롤이 필요합니다. 이 파일 업로드 인터페이스 구성 요소를 추가하십시오.
질문: 여기에서 파일을 선택했는데 파일 이름이 표시되지 않는 이유는 무엇입니까
? 해결책:
js 파일이 위에서 아래로 실행되기 때문입니다.
효과:
파일을 선택하면 파일 이름이 성공적으로 표시됩니다.성공한 이유는 bsCustomFileInput.init()를 통해 전체 페이지를 로드한 후 custom-file-input 구성 요소를 초기화하기 때문입니다. 파일 이름이 성공적으로 표시되도록 하십시오.
메소드 매개변수 소개:
요청 매개변수가 너무 많으면 하나씩 작성할 수 없으므로 요청 매개변수를 객체에 캡슐화하면 됩니다.
완전한 코드
파일을 추가하는 페이지:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<!-- 引入css样式,用 link 元素 , stylesheet 样式单 , .gz表示是打包的,但是springboot会自动解包 -->
<!-- 引入 Bootstrap 的 Web Jar 中的 CSS 样式 -->
<link rel="stylesheet" th:href="@{'/webjars/bootstrap/css/bootstrap.min.css'}">
<!-- jquery 放在 bootstrap 前面,因为 bootstrap 需要依赖到 jquery -->
<!-- 引入 jQuery 的 Web Jar 中的 js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/jquery/jquery.min.js'}"></script>
<!-- 引入 Bootstrap 的 Web Jar 中的 js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/bootstrap/js/bootstrap.bundle.min.js'}"></script>
<!-- 引入 popper 的 Web Jar 中的 Js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/popper.js/umd/popper.min.js'}"></script>
<!-- 引入文件上传的界面组件的js -->
<script type="text/javascript"
th:src="@{'/webjars/bs-custom-file-input/dist/bs-custom-file-input.js'}"></script>
<script>
// <!-- 当整个页面加载完成的时候,就执行这个函数,保证这个函数是在页面加载完成后才执行初始化 -->
// <!-- 初始化 custom file input 组件的 JS 脚本 -->
$(function () {
bsCustomFileInput.init();
})
</script>
</head>
<body>
<div class="container">
<h4>添加图书</h4>
<!-- 保证请求是以 multipart/form-data 格式提交请求
不用这个格式,文件上传的数据都不会传到服务器 -->
<form method="post" th:action="@{/addBookFile}" enctype="multipart/form-data">
<div class="form-group row">
<label for="name" class="col-sm-2 col-form-label">图书名:</label>
<div class="col-sm-7">
<input type="text" id="name" name="name"
class="form-control" placeholder="请输入图书名">
</div>
<div class="col-sm-3 text-danger">
<span th:if="${book != null}" th:errors="${book.name}">错误提示</span>
</div>
</div>
<div class="form-group row">
<label for="cover" class="col-sm-2 col-form-label">图书封面:</label>
<div class="col-sm-7">
<!-- custom-file 用来保证页面比较好看 -->
<div class="custom-file">
<input type="file" id="cover" name="cover"
class="custom-file-input">
<label class="custom-file-label" for="cover">选择文件</label>
</div>
</div>
<div class="col-sm-3 text-danger">
<span th:if="${book != null}" th:errors="${book.cover}">错误提示</span>
</div>
</div>
<div class="form-group row">
<div class="col-sm-6 text-right">
<button type="submit" class="btn btn-primary">添加</button>
</div>
<div class="col-sm-6">
<button type="reset" class="btn btn-danger">重设</button>
</div>
</div>
</form>
</div>
</body>
</html>
구성 파일:
파일 업로드를 위한 디렉터리를 설정합니다.
프런트 엔드에서 전송된 파일 데이터를 캡슐화하는 Book 개체를 만듭니다.
백엔드 비즈니스 로직 코드:
package cn.ljh.file_upload.controller;
import cn.ljh.file_upload.domain.Book;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.UUID;
@Controller
public class FileUpLoadController {
//指定文件上传的存储路径,把路径写在配置文件中,通过 @Value 注解来获取该属性值
@Value("${ljh.myfile.savePath}")
private String destPath;
@SneakyThrows
@PostMapping("/addBookFile")
public String addBookFile(Book book, Model model){
//处理文件上传逻辑:也就是把文件内容保存到服务器的指定路径下。
//创建文件
File file = new File(destPath);
//判断文件是否存在
if (!file.exists()){
//如果没有该文件,也就是该目录不存在,则创建该目录
file.mkdir();
}
/*
* destFile 是服务器端重新生成的一个文件名,而且保留了原来的拓展名。
* 比如 我们上传文件的拓展名是 .jpg , 服务器生成的这个 destFile 文件,
* 不仅要有上传的文件的内容,拓展名(后缀名)也要保持一致
* Extension: 扩展 Original:起初的、原先的
*/
//获取上传文件的原拓展名
//获取上传文件的文件名
String originalFilename = book.getCover().getOriginalFilename();
//通过String工具类来获取这个文件名的扩展名
String ext = StringUtils.getFilenameExtension(originalFilename);
/*
* destPath + "/" : 指定文件上传的路径 ,路径和文件名之间需要加一个斜杠 /
* UUID.randomUUID().toString() : 生成文件名
* "." + ext : 文件的扩展名(后缀名)
*/
//生成一个新的文件
File destFile = new File(destPath + "/" + UUID.randomUUID().toString() + "." + ext);
//获取要上传文件的内容,返回是MultipartFile对象
MultipartFile cover = book.getCover();
//MultipartFile对象有一个方法 transferTo :可以将上传文件的内容写入到指定的文件destFile中。
cover.transferTo(destFile);
model.addAttribute("tip" , originalFilename + "文件上传成功!");
return "uploadfile_success";
}
}
파일을 업로드한 후 페이지로 돌아가기:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>上传成功</title>
<!-- 引入css样式,用 link 元素 , stylesheet 样式单 , .gz表示是打包的,但是springboot会自动解包 -->
<!-- 引入 Bootstrap 的 Web Jar 中的 CSS 样式 -->
<link rel="stylesheet" th:href="@{'/webjars/bootstrap/css/bootstrap.min.css'}">
<!-- jquery 放在 bootstrap 前面,因为 bootstrap 需要依赖到 jquery -->
<!-- 引入 jQuery 的 Web Jar 中的 js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/jquery/jquery.min.js'}"></script>
<!-- 引入 Bootstrap 的 Web Jar 中的 js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/bootstrap/js/bootstrap.bundle.min.js'}"></script>
<!-- 引入 popper 的 Web Jar 中的 Js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/popper.js/umd/popper.min.js'}"></script>
</head>
<body>
<div class="container">
<h4>文件上传成功</h4>
<div class="text-primary" th:text="${tip}">提示</div>
</div>
</body>
</html>
효과:
파일 에코
▲ 파일 업로드 에코를 확인하시길 바랍니다
能看到上传后文件的图片,
(1)需要将服务器保存文件的所使用的文件名传回给视图页面。
(2)还需要将保存文件的路径设置为Spring Boot的静态资源路径。
添加额外的静态资源路径时,额外添加的磁盘最后必须要有一个斜杠结尾
코드 데모:
추가 조사가 진행 중이므로 이미지를 성공적으로 에코할 수 없습니다.
업로드 후 파일 이름을 반환하려면 매개변수를 캡슐화하는 객체에 fileName 속성을 추가하세요.
파일명을 분리하여 book 객체에 설정합니다.
추가 정적 리소스 경로를 추가하는 구성 클래스를 만들고, 프로젝트를 읽고 표시할 수 있도록 이미지의 디스크 경로를 정적 리소스 경로에 매핑합니다.
파일이 업로드된 후 페이지에서 에코된 코드에는 이 문장만 있습니다.
구성된 디스크 경로의 끝에 슬래시를 추가해야 합니다.
결과:
잘 안 됐어요.
모든 코드:
마지막으로 에코 코드가 추가됩니다(에코는 성공하지 못했으며 추가 조사가 진행 중입니다).
색인
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<!-- 引入css样式,用 link 元素 , stylesheet 样式单 , .gz表示是打包的,但是springboot会自动解包 -->
<!-- 引入 Bootstrap 的 Web Jar 中的 CSS 样式 -->
<link rel="stylesheet" th:href="@{'/webjars/bootstrap/css/bootstrap.min.css'}">
<!-- jquery 放在 bootstrap 前面,因为 bootstrap 需要依赖到 jquery -->
<!-- 引入 jQuery 的 Web Jar 中的 js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/jquery/jquery.min.js'}"></script>
<!-- 引入 Bootstrap 的 Web Jar 中的 js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/bootstrap/js/bootstrap.bundle.min.js'}"></script>
<!-- 引入 popper 的 Web Jar 中的 Js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/popper.js/umd/popper.min.js'}"></script>
<!-- 引入文件上传的界面组件的js -->
<script type="text/javascript"
th:src="@{'/webjars/bs-custom-file-input/dist/bs-custom-file-input.js'}"></script>
<script>
// <!-- 当整个页面加载完成的时候,就执行这个函数,保证这个函数是在页面加载完成后才执行初始化 -->
// <!-- 初始化 custom file input 组件的 JS 脚本 -->
$(function () {
bsCustomFileInput.init();
})
</script>
</head>
<body>
<div class="container">
<h4>添加图书</h4>
<!-- 保证请求是以 multipart/form-data 格式提交请求
不用这个格式,文件上传的数据都不会传到服务器 -->
<form method="post" th:action="@{/addBookFile}" enctype="multipart/form-data">
<div class="form-group row">
<label for="name" class="col-sm-2 col-form-label">图书名:</label>
<div class="col-sm-7">
<input type="text" id="name" name="name"
class="form-control" placeholder="请输入图书名">
</div>
<div class="col-sm-3 text-danger">
<span th:if="${book != null}" th:errors="${book.name}">错误提示</span>
</div>
</div>
<div class="form-group row">
<label for="cover" class="col-sm-2 col-form-label">图书封面:</label>
<div class="col-sm-7">
<!-- custom-file 用来保证页面比较好看 -->
<div class="custom-file">
<input type="file" id="cover" name="cover"
class="custom-file-input">
<label class="custom-file-label" for="cover">选择文件</label>
</div>
</div>
<div class="col-sm-3 text-danger">
<span th:if="${book != null}" th:errors="${book.cover}">错误提示</span>
</div>
</div>
<div class="form-group row">
<div class="col-sm-6 text-right">
<button type="submit" class="btn btn-primary">添加</button>
</div>
<div class="col-sm-6">
<button type="reset" class="btn btn-danger">重设</button>
</div>
</div>
</form>
</div>
</body>
</html>
uploadfile_success.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>上传成功</title>
<!-- 引入css样式,用 link 元素 , stylesheet 样式单 , .gz表示是打包的,但是springboot会自动解包 -->
<!-- 引入 Bootstrap 的 Web Jar 中的 CSS 样式 -->
<link rel="stylesheet" th:href="@{'/webjars/bootstrap/css/bootstrap.min.css'}">
<!-- jquery 放在 bootstrap 前面,因为 bootstrap 需要依赖到 jquery -->
<!-- 引入 jQuery 的 Web Jar 中的 js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/jquery/jquery.min.js'}"></script>
<!-- 引入 Bootstrap 的 Web Jar 中的 js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/bootstrap/js/bootstrap.bundle.min.js'}"></script>
<!-- 引入 popper 的 Web Jar 中的 Js 脚本 -->
<script type="text/javascript" th:src="@{'/webjars/popper.js/umd/popper.min.js'}"></script>
</head>
<body>
<div class="container">
<h4>文件上传成功</h4>
<div class="text-primary" th:text="${tip}">提示</div>
<!-- 文件上传后进行回显 -->
<img th:src="@{'/uploads/' + ${book.fileName}}">
</div>
</body>
</html>
책
package cn.ljh.file_upload.domain;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;
@Data
public class Book {
private Integer id;
private String name;
//用来封装前端传来的文件数据
private MultipartFile cover;
//用于封装上传之后的文件名
private String fileName;
}
FileUpLoadController
package cn.ljh.file_upload.controller;
import cn.ljh.file_upload.domain.Book;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.UUID;
@Controller
public class FileUpLoadController {
//指定文件上传的存储路径,把路径写在配置文件中,通过 @Value 注解来获取该属性值
@Value("${ljh.myfile.savePath}")
private String destPath;
@SneakyThrows
@PostMapping("/addBookFile")
public String addBookFile(Book book, Model model){
//处理文件上传逻辑:也就是把文件内容保存到服务器的指定路径下。
//创建文件
File file = new File(destPath);
//判断文件是否存在
if (!file.exists()){
//如果没有该文件,也就是该目录不存在,则创建该目录
file.mkdir();
}
/*
* destFile 是服务器端重新生成的一个文件名,而且保留了原来的拓展名。
* 比如 我们上传文件的拓展名是 .jpg , 服务器生成的这个 destFile 文件,
* 不仅要有上传的文件的内容,拓展名(后缀名)也要保持一致
* Extension: 扩展 Original:起初的、原先的
*/
//获取上传文件的原拓展名
//获取上传文件的文件名
String originalFilename = book.getCover().getOriginalFilename();
//通过String工具类来获取这个文件名的扩展名
String ext = StringUtils.getFilenameExtension(originalFilename);
/*
* destPath + "/" : 指定文件上传的路径 ,路径和文件名之间需要加一个斜杠 /
* UUID.randomUUID().toString() : 生成文件名
* "." + ext : 文件的扩展名(后缀名)
*/
//生成一个新的文件
//生成文件名
String fileName = UUID.randomUUID().toString() + "." + ext;
File destFile = new File(destPath + "/" + fileName);
//获取要上传文件的内容,返回是MultipartFile对象
MultipartFile cover = book.getCover();
//MultipartFile对象有一个方法 transferTo :可以将上传文件的内容写入到指定的文件destFile中。
cover.transferTo(destFile);
//文件上传成功后回显的名字
book.setFileName(fileName);
model.addAttribute("tip" , originalFilename + "文件上传成功!");
return "uploadfile_success";
}
}
파일업로드구성
package cn.ljh.file_upload.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//用于文件上传成功后的回显的处理类
@Configuration
public class FileUpLoadConfig implements WebMvcConfigurer {
//指定文件上传的存储路径,把路径写在配置文件中,通过 @Value 注解来获取该属性值
@Value("${ljh.myfile.savePath}")
private String destPath;
//重写这个方法,用于添加额外的静态资源路径
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//将文件上传的destPath这个磁盘路径添加成静态资源路径,并映射到 /uploads/** 路径下。
registry.addResourceHandler("/uploads/**")
.addResourceLocations(destPath);
}
}
application.yml
#指定文件上传后保存的路径
ljh:
myfile:
savePath: F:\myCode\crazyCode\SpringBoot\springboot07\uploads\