SpringBoot——Web开发
5.5 文件上传
文件上传的章节,之前在学Spring还是JavaWeb的时候,用JSP写过
5.5.1 文件上传
那么,SpringBoot怎么实现文件上传呢?
知识点:
1、文件上传,必须得用表单form来提交。
2、提交的表单必须要是post请求。get请求能提交的文件太小啦!!!
3、form表单必须有属性enctype="multipart/form-data"属性
4、单文件上传,直接用input标签,type为file
5、多文件上传,也用input标签,type也是file,但是要多一个multiple属性。
首先,我们写一个显示页面:
upload.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>文件上传演示</title>
</head>
<body>
<!--
上传的表单必须是post请求
而且必须有enctype="multipart/form-data"属性,服务器才知道这是文件上传请求
-->
<form th:action="@{/upload}" enctype="multipart/form-data" method="post">
用户名:<input type="text" name="username"/><br>
<!--单文件上传,type直接写file-->
头 像:<input type="file" name="headImg"/><br>
<!--多文件上传加multiple属性-->
生活照:<input type="file" name="photos" multiple><br>
<input type="submit" value="上传">
</form>
</body>
</html>
然后我们写我们的控制器方法,一个用来跳转到upload.html页面,一个用来处理上传过来的文件。
知识点:
1、提交过来的普通数据,我们只需要用@RequestParam注解加他的name直接获取即可。
2、提交过来的单文件,我们用@RequestPart注解加他的name获取,用MultipartFile对象接收。
3、提交过来的多个文件,我们用@RequestPart注解加他的name获取,用MultipartFile[]数组对象接收。
UploadController.java代码如下:
package com.example.boot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
@Controller
public class UploadController {
//将请求转发到upload.html页面
@GetMapping("/upload")
public String toUpload(){
return "upload";
}
//接收提交的数据信息
@PostMapping("/upload")
public String receiveFile(@RequestParam("username") String username,
@RequestPart("headImg") MultipartFile headerImg,
@RequestPart("photos") MultipartFile[] photos){
System.out.println("username="+username);
System.out.println("headImg="+headerImg);
System.out.println("photos="+photos);
return "success";
}
}
运行:
我们在头像传入一个图片,在生活照传入n个图片(多了可能会爆,所以我传了两张)
如果传入的文件太多,导致上传的字节数大于1048576字节(也就是1MB)的话,会直接报500错误。
所以我们暂时先传两个小图片,然后点击上传,跳转到success.html页面,后台输出:
5.5.2 文件解析
我们将控制器方法的代码修改为:
直接这么拿肯定是不行滴!我们既然拿到图片了,那肯定要把他放到我们的服务器啊(虽然我没有,那就放本地咯)。
@PostMapping("/upload")
public String receiveFile(@RequestParam("username") String username,
@RequestPart("headImg") MultipartFile headerImg,
@RequestPart("photos") MultipartFile[] photos) throws IOException {
System.out.println("username="+username);
System.out.println("headImg="+headerImg);
System.out.println("photos="+photos);
//判断文件是否为空,非空则保存到服务器或自己的磁盘
if(! headerImg.isEmpty()){
//获取文件原始名称
String headImgName = headerImg.getOriginalFilename();
headerImg.transferTo(new File(("D:\\img\\"+headImgName)));
}
System.out.println(photos.length);
//判断文件数组是否有文件,有则遍历保存到服务器或磁盘
if (photos.length > 0){
for (MultipartFile photo : photos) {
if(! photo.isEmpty()){
String photoName = photo.getOriginalFilename();
photo.transferTo(new File(("D:\\img\\"+photoName)));
}
}
}
return "success";
}
运行结果:
点击上传后,我们到D盘的img目录下:(文件都过来了)
5.5.3 修改默认文件上传最大值
前面,我们提到了如果传过去的文件太大的话,那么服务器会报错500.
那么,我们如果一定要传大图片怎么搞呢?简单,修改一下我们的默认配置就好了。在application.yml中使用spring.servlet.multipart.max-file-size:
直接设置即可。
spring:
servlet:
multipart:
max-file-size: 10MB
我们还可以配置我们默认上传的整个请求的最大值。使用spring.servlet.multipart.max-request-size
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 20MB
5.5.4 服务器怎么判断请求是不是文件上传请求
其实很简单,偷看一下源码:
通过判断请求头的ContentType的前缀是不是multipart/,就可以判断他是不是文件上传请求。(为什么不是判断multipart/form-data,因为源码中this.strictServletCompliance的默认值是false。)
public boolean isMultipart(HttpServletRequest request) {
return StringUtils.startsWithIgnoreCase(request.getContentType(), this.strictServletCompliance ? "multipart/form-data" : "multipart/");
}
文件上传请求的Content-Type,里面有我们在form表单写的multipart/form-data。