小案例。
进行文件上传时前端要做的准备:
- 使用form表单提交
- 请求方式设定为post
- 设定type=“file”
- 请求编码方式设置为multipart/form-data
浏览器端代码
<form action="/workorder/upload" enctype="multipart/form-data" method="post">
上传文本:<input type="text" name="username"><br/>
<!--表单要上传文件附件,input标签的type属性要选file,name属性要和服务端的参数名保持一致-->
上传文件:<input type="file" name="file1"><br/>
上传文件:<input type="file" name="file2"><br/>
<input type="submit" value="提交">
</form>
服务端要做的准备:
先要引入这个jar包
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
服务端代码
/**
* 上传附件
* @return
*/
@PostMapping(value = "/upload", consumes = "multipart/form-data")
@ResponseBody
public Map<String, String> upload(@RequestParam("file1") MultipartFile file1,
@RequestParam("file2") MultipartFile file2,
HttpSession session){
Map<String, String> result = new HashMap<>(2);
try{
//获取服务器的真实路径
String path = session.getServletContext().getRealPath("/");
System.out.println(path);
path = path + "/upload/";
//判断文件路径是否存在,不存在就创建文件夹
File file = new File(path);
if (!file.exists()){
file.mkdirs();
}
file1.transferTo(new File(path, file1.getOriginalFilename()));
file2.transferTo(new File(path, file2.getOriginalFilename()));
result.put("msg", "成功");
result.put("information", "上传成功");
}catch (Exception e){
result.put("msg", "失败");
result.put("information", e.getMessage());
}
return result;
}
有时候上传文件会出现异常:
org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field fileName exceeds its maximum permitted size of 1048576 bytes.
这是因为默认的最大上传大小是2M,可以在application.properties文件中添加配置:
spring.servlet.multipart.max-file-size=8MB
multipart还有一些其他的配置大家可以自己去摸索
以上代码是一个模板,具体可以根据实际的业务需求做具体修改。
啦啦啦~你以为这样就完了吗,作为一个好奇心旺盛的程序员当然要学习点理论的东西了。
理论篇:
我们先看一段http1.1请求上传文件时候的请求头Header样例(注意我画了红色框框的位置~)
前端form表单如下图
HTTP请求的消息正文是2进制数据,是请求中附带的用户提交的数据。他可能是用户上传的附件,json信息等。一个请求可能不包含消息正文部分。
当一个请求包含消息正文部分时,通常消息头中会包含两个用于说明消息正文的头信息:
Content-Type:用于说明消息正文的数据类型
Content-Length:用于说明消息正文共多少字节
PS:
HTTP协议中的请求行和消息头部分是文本数据,但是字符集只能是ISO8859-1规定字符。所以是不能直接附带汉字信息的。
我们可以看到上面第一张图我画框框的内容
Content-Type: multipart/form-data; boundary=---------------------------67983052926559
这其中multipart/form-data
该属性表明发送的请求体的内容是多表单元素的,通俗点讲,就是有各种各样的数据,可能有二进制的文件数据,也可能有文本数据等等。
使用multipart/form-data
后面会带有一个boundary
属性,来用将提交的表单数据进行分隔,就像上图中我同一个请求上传了三段数据,这三段数据就会被boundary
分隔开。