前端提交文件到后端的方法
在项目中我们经常会遇到图片的上传问题,对于后端工程师来说,前端相对来说很薄弱.在此总结了两种简单的提交图片到后台的方法.
一. 表单同步提交
在商品管理时,新增一个商品时,需要为商品插入一个图片,在这里我们使用表单提交的方式,将表单的数据全部提交到后台.步骤如下
1. 搭建前端界面
作为一个强迫症,为了界面不那么丑使用了bootstrap的样式,所以需要导入bootstrap的包,
bootstrap.min.js和bootstrap.min.css;
还有jquery的包也需要导入;
界面大概是这样;
2. 作为强迫症,选择图片必须要看到预览图.
大概思路是,在文件上传框添加一个change事件,然后获取当前文件的路径,在将其路径赋值给图片的src属性;
实现代码如下:
<label for="" class="col-sm-2 control-label">车辆图片</label>
<div class="col-sm-4 pfilediv">
<img src="" style="width: 200px;height: 100px" class="img" id="carimg"/>
</div>
<div class="col-sm-4 pfilediv">
<input type="file" id="pfile" name="carPic" style="margin-top: 70px ; margin-left: 20px">
</div>
<script type="text/javascript">
$("#pfile").change(function () {
var file = this.files[0];
if (window.FileReader) {
var reader = new FileReader();
reader.readAsDataURL(file);
//监听文件读取结束后事件
reader.onloadend = function (e) {
$("#carimg").attr("src", e.target.result);
//e.target.result就是最后的路径地址
};
}
})
</script>
写完后大概长这样;
3. 表单提交
图片上所有的信息实际上就是一个表单,在表单提交时会将其提交到后台,但为了能提交文件到后台,我们需要为表单做一些设置;
<form id="inputForm" class="form-horizontal"
action="/car/addCar" enctype="multipart/form-data" method="post">
action 是提交到哪里
eqctype ="multipart/form-data" 是支持提交文件
此外提交方式必须为 method="post";
4. 前端完整代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>车</title>
<link rel="stylesheet" href="../css/bootstrap.min.css">
<script type="application/javascript" src="../js/jquery-3.3.1.js"></script>
<script type="application/javascript" src="../js/bootstrap.min.js"></script>
</head>
<style>
#uppp {
width: 600px;
height: 400px;
}
#md1, #md2 {
width: 260px;
float: left;
}
#md1 {
width: 100px;
margin-right: 10px;
}
.top {
margin-top: 40px;
margin-left: 40px;
}
.info {
width: 600px;
height: 500px;
margin: 20px 20px;
}
#addsub {
margin-left: 100px;
}
#sell {
margin-top: 20px;
margin-left: 70px;
}
.bb {
margin-left: 400px;
}
</style>
<body>
<div class="bb">
<form id="inputForm" class="form-horizontal" action="/car/addCar" enctype="multipart/form-data"
method="post">
<div class="info">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true"></span>
</button>
<div>
<span class="itemTitle-red ">填写车辆信息</span><br>
</div>
</div>
<div class="modal-body" id="">
<div class="form-group">
<label for="cname" class="col-sm-2 control-label">车辆名称</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="cname" name="cname">
</div>
</div>
<div class="form-group">
<label for="type" class="col-sm-2 control-label">车辆类型</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="type" name="type">
</div>
</div>
<div class="form-group">
<label for="sitnum" class="col-sm-2 control-label">座位数</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="sitnum" name="sitnum">
</div>
</div>
<div class="form-group">
<label for="price" class="col-sm-2 control-label">价格/天</label>
<div class="col-sm-8">
<input type="text" class="form-control capital mui-input-clear" id="price"
name="price">
</div>
</div>
<div class="form-group">
<label for="" class="col-sm-2 control-label">车辆图片</label>
<div class="col-sm-4 pfilediv">
<img src="" style="width: 200px;height: 100px" class="img" id="carimg"/>
</div>
<div class="col-sm-4 pfilediv">
<input type="file" id="pfile" name="carPic" style="margin-top: 70px ; margin-left: 20px">
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-success "
id="addsub" value="新增车辆">
</input>
</div>
</div>
</form>
</div>
</body>
<script type="text/javascript">
$("#pfile").change(function () {
var file = this.files[0];
if (window.FileReader) {
var reader = new FileReader();
reader.readAsDataURL(file);
//监听文件读取结束后事件
reader.onloadend = function (e) {
$("#carimg").attr("src", e.target.result); //e.target.result就是最后的路径地址
};
}
})
</script>
</html>
5. 后端的接收
//添加车辆信息
@RequestMapping(value = "/addCar", method = RequestMethod.POST)
@ResponseBody
public Msg2 addCar(Car car, MultipartFile carPic) {
//上传图片,成功返回存放路径
String filePath = QiNiuUpload.uploadFile(carPic);
System.out.println(filePath );
if (fileName != null) {
//将文件的存放路径赋值给商品对象,插入到数据库中
car.setPicture(filePath );
//将整个car对象插入数据库中
int addcar = carService.addCar(car);
if (addcar != 0) {
return new Msg2(1, "新增成功");
}
}
return new Msg2(0, "添加失败");
}
二. 表单异步提交
在我们修改商品图片的时候,我们往往希望图片的上传是异步上传的,在这里为了简单实现,我使用jquery的from插件来实现文件的异步上传.
1 . 百度下载jquery的from插件.jquery-form.js
2. 在jsp页面导入jquery-form.js包
3. 创建vue对象与表单双向绑定
为了模拟修改商品的场景,我们将表单的数据设置一些初始值.
3. 上传图片并返回图片的云存储路径
3.1 为file文件上传框添加change()事件
在这里我们为文件上传的input添加一个@change事件,这是一个vue语法,类似于js的修改事件.当我们修改了input的文件,会触发这个事件.
3.2 在change事件中设置表单异步上传
$("#inputForm").ajaxSubmit(options);
其中的options是设置一些上传参数的,具体说明有注释,等价于
<form id="inputForm" action="/car/update" enctype="multipart/form-data"
method="post">
代码如下:
fileup: function () {
alert("上传图片事件触发")
var options = {
type: 'POST',
dataType: 'json',
url: '/car/upFile',
success: function showResponse(responseText) {
if (responseText.code == 1) {
alert(responseText.code)
carinfos.carInfo.picture = responseText.info;
alert(carinfos.carInfo.picture);
} else {
alert(responseText.info);
}
},
error: function (xhr, status, err) {
alert("上传失败");
},
resetForm: true // 成功提交后,重置表单填写内容
};
$("#inputForm").ajaxSubmit(options);
}
我们将返回的图片地址赋值给vue绑定的变量,它会实时的显示在页面上,如下图
4. 将整个表单的数据再次异步提交,此时提交的数据是插入到数据库中.
完整的HTML页面代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>车</title>
<link rel="stylesheet" href="../css/bootstrap.min.css">
<script type="application/javascript" src="../js/jquery-3.3.1.js"></script>
<script type="application/javascript" src="../js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<%--一. 导入异步上传表单的插件--%>
<script type="text/javascript" src="../js/jquery-form.js"></script>
</head>
<style>
#uppp {
width: 600px;
height: 400px;
}
#md1, #md2 {
width: 260px;
float: left;
}
#md1 {
width: 100px;
margin-right: 10px;
}
.top {
margin-top: 40px;
margin-left: 40px;
}
.info {
width: 600px;
height: 500px;
margin: 20px 20px;
}
#addsub {
margin-left: 100px;
}
#sell {
margin-top: 20px;
margin-left: 70px;
}
.bb {
margin-left: 400px;
}
</style>
<body>
<div class="bb">
<form id="inputForm" class="form-horizontal" enctype="multipart/form-data"
method="post">
<div class="info">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true"></span>
</button>
<div>
<span class="itemTitle-red ">填写车辆信息</span><br>
</div>
</div>
<div class="modal-body" id="">
<div class="form-group">
<label for="cid" class="col-sm-2 control-label">车辆ID</label>
<div class="col-sm-8">
<input type="text" readonly class="form-control" id="cid" name="cid" v-model="carInfo.cid">
</div>
</div>
<div class="form-group">
<label for="cname" class="col-sm-2 control-label">车辆名称</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="cname" name="cname" v-model="carInfo.cname">
</div>
</div>
<div class="form-group">
<label for="type" class="col-sm-2 control-label">车辆类型</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="type" name="type" v-model="carInfo.type">
</div>
</div>
<div class="form-group">
<label for="sitnum" class="col-sm-2 control-label">座位数</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="sitnum" name="sitnum" v-model="carInfo.sitnum">
</div>
</div>
<div class="form-group">
<label for="price" class="col-sm-2 control-label">价格/天</label>
<div class="col-sm-8">
<input type="text" class="form-control capital mui-input-clear" id="price"
name="price" v-model="carInfo.price">
</div>
</div>
<div class="form-group">
<label for="" class="col-sm-2 control-label">车辆图片</label>
<div class="col-sm-4" style="width: 80px;height: 80px">
<input type="image" class="img" :src="carInfo.picture"
style="width: 80px;height: 80px;">
</div>
<div class="col-sm-4 pfilediv">
<input type="file" id="pfile" name="carimg" @change="fileup()"
style="margin-top: 40px ; margin-left: 20px">
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-success "
id="addsub" value="新增车辆">
</input>
</div>
</div>
</form>
</div>
</body>
<script type="text/javascript">
/*二 。 将表单数据与vue对象双向绑定*/
var carinfos = new Vue({
el: '#inputForm',
data: {
carInfo: {
cid: 1,
cname: "大众帕萨特",
picture: "https://web-api.chesudi.com/img/carTypeimage/ScarTypeimage/%E5%A4%A7%E4%BC%97%E5%B8%95%E8%90%A8%E7%89%B9.png",
type: "手自一体",
sitnum: 5,
price: 982,
number: 5,
type: "手自一体"
},
},
methods: {
/*三。 添加图片的修改事件*/
fileup: function () {
alert("上传图片事件触发")
var options = {
type: 'POST',//提交方式必须为post
dataType: 'json',//接受后端返回值的格式
url: '/car/upFile',//提交的位置
success: function showResponse(responseText) {
if (responseText.code == 1) {
//将返回的涂炭地址赋值给表单的图片显示的input
carinfos.carInfo.picture = responseText.info;
} else {
alert(responseText.info);
}
},
error: function (xhr, status, err) {
alert("上传失败");
},
resetForm: true // 成功提交后,重置表单填写内容
};
$("#inputForm").ajaxSubmit(options);
//设置表单的异步上传.id为提交表单的id
}
}
})
// 四 . 用户修改确认按钮
function update2() {
if (confirm("确认修改?")) {
// 向后端发出修改请求后,获得成功信息,再关闭模态窗体
$.ajax({
type: 'put',
url: '/car/update',
// 请求数据 ,将json对象转为字符串
data: JSON.stringify(carinfos.carInfo),
// 定义发送请求数据类型
contentType: 'application/json',
// 定义接收的相应数据类型
dataType: 'json',
success: function (data) {
if (data.code == 1) {
// 重新加载数据列表
loadPage(1)
} else {
alert("修改失败")
}
}
});
$("#myModal").modal("hide");
}
}
</script>
</html>
5. 后端接受数据;
因为这个例子我们向服务器提交了两次请求,所以会有两个接口来处理数据.
1. 处理上传图片的接口
上传图片我们使用七牛云来上传,具体流程看我的上一篇博客spring-mvc文件云存储功能
//只上传图片的
@RequestMapping(value = "/upFile", method = RequestMethod.POST)
@ResponseBody
public Msg2 upFile(HttpServletRequest request, MultipartFile carimg) {
//在这里使用七牛云上传文件
String fileName = FileUp.fileUp(request, carimg);
System.out.println(fileName);
if (fileName != null) {
return new Msg2(1, fileName);
//msg2,是自己定义的传递消息的工具类,封装状态码和返回数据
}
return new Msg2(0, "上传没有成功");
}
2. 处理修改商品信息的接口
//修改
@RequestMapping(value = "/update", method = RequestMethod.PUT)
@ResponseBody
public Msg2 updateAll(@RequestBody Car car) {
int update = carService.updateCar(car);
if (update != 0) {
return new Msg2(1, update);
}
return new Msg2(0, "错误修改");
}