一、文件上传的原理
在前端页面,我们可以提交文件,点击提交以后,文件的路径会被传到控制层,然后将这个路径存到数据库中。
当我们想查询我们添加的文件时,页面会发送请求到控制层,执行查询业务,像数据库中查询我们的文件路径,如果是ajax异步请求,在控制层封装成json数据最后返回到前端页面。
二、文件上传到本地服务器(Tomcat)
实现步骤:
(1)在pom.xml中引入文件上传的依赖--commons-fileupload
<!--文件上传的依赖-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
(2)简单创建一个前端页面,包含文件上传的表单和提交按钮
<%--
Created by IntelliJ IDEA.
User: m1762
Date: 2022/6/9
Time: 20:06
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="upload01" enctype="multipart/form-data" method="post">
<input type="file" name="file"/><br>
<input type="submit" value="提交"/>
</form>
</body>
</html>
注意:
- method提交方式必须为:post
- enctype:默认为:application/x-www-form-urlencoded,这里需要改为:multipart/form-data
- input的type为file类型的标签,必须要有name属性。
(3)在springmvc中配置文件上传解析器
<!--
id的名称必须叫multipartResolver
-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--这里的单位为字节10M*1024K*1024-->
<property name="maxUploadSize" value="10485760"/>
</bean>
注意:id名必须为: multipartResolver
(4)在controller包下写upload01的接口方法类
package com.lrs.controller;
import com.lrs.util.CommenRuselt;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* @作者:刘壬杉
* @创建时间 2022/6/9
**/
@Controller
public class UploadController {
@RequestMapping(value = "/upload01")
public String upload01(HttpServletRequest request, MultipartFile file) throws IOException {
//(1)得到本地服务目录的地址
String path = request.getSession().getServletContext().getRealPath("upload");
System.out.println(path);
//(2)判断该目录是否存在 不存在则创建
File file1 = new File(path);
if (!file1.exists()){
file1.mkdirs();
}
//(3)把myfile保存到本地服务中某个文件夹下。
String filename = UUID.randomUUID().toString().replace("-","")+file.getOriginalFilename();
//把myfile转移到目标目录下
File target = new File(path+"/"+filename);
file.transferTo(target);
return "";
}
注意:传参处的MultipartFile 类型的变量名必须和上面 步骤(2)中的input 内type属性为file的标签中的name中的名称一致!
运行效果:
三、elementui+vue+axios实现文件上传
(1)前端页面布局
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页面</title>
<%--引入css样式--%>
<link href="css/index.css" rel="stylesheet"/>
<%--引入vue的js--%>
<script type="text/javascript" src="js/vue.js"></script>
<%--引入axios的js--%>
<script type="text/javascript" src="js/axios.min.js"></script>
<%--引入elementui的js--%>
<script type="text/javascript" src="js/index.js"></script>
<%--引入qs--%>
<script type="text/javascript" src="js/qs.min.js"></script>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
</head>
<body>
<div id="app">
<el-upload
class="avatar-uploader"
<%--action:文件上传的路径--%>
action="upload02"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
</body>
<script>
var app = new Vue({
el:"#app",
data:{
imageUrl:"",
},
methods:{
//上传成功后触发的方法
handleAvatarSuccess(res, file) {
this.imageUrl = res.data
},
//上传前触发的方法
beforeAvatarUpload(file) {
//设定上传文件的类型和大小
const isJPG = file.type === 'image/jpeg';
const isPNG = file.type === 'image/png';
const isLt2M = file.size / 1024 / 1024 < 5;
if (!isJPG && !isPNG) {
this.$message.error('上传头像图片只能是 JPG或PNG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 5MB!');
}
return (isPNG || isJPG) && isLt2M;
}
}
})
</script>
</html>
注意:elementui中提交文件的表单 中的name属性默认为file。
(2)后端接口
package com.lrs.controller;
import com.lrs.util.CommenRuselt;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/**
* @作者:刘壬杉
* @创建时间 2022/6/9
**/
@Controller
public class UploadController {
@RequestMapping(value = "/upload02")
@ResponseBody
public CommenRuselt upload02(HttpServletRequest request, MultipartFile file) {
try {
String path = request.getSession().getServletContext().getRealPath("upload");
File file1 = new File(path);
if (!file1.exists()){
file1.mkdirs();
}
String filename = UUID.randomUUID().toString().replace("-","")+file.getOriginalFilename();
File target = new File(path+"/"+filename);
file.transferTo(target);
Object data = "http://localhost:8080/s/upload/"+filename;
CommenRuselt commenRuselt = new CommenRuselt(2000,"上传成功",data);
return commenRuselt;
} catch (IOException e) {
e.printStackTrace();
}
CommenRuselt ruselt = new CommenRuselt(5000,"上传失败",null);
return ruselt;
}
}
注意:前端发送的是axios异步请求,后端必须响应给前端一个json格式数据。@ResponseBody注解为springmvc中内置的json转换方法。
四、注册阿里云服务器并将文件上传到OSS
上传到本地服务器的缺点: 如果搭建集群,导致文件无法在集群中共享。 它的解决方法就是把文件专门上传到一个文件服务器上,这些tomcat服务器都操作同一个文件服务器。
4.1 申请OSS文件服务
4.2 在OSS界面上操作文件上传
(1)创建bucket容器
(2)在该bucket中通过网页面板的形式操作该bucket。但是实际开发我们应该通过java代码往bucket中上传文件。
4.3 申请阿里云的密钥