本文介绍的方法在上传文件时先上传到本地,在发请求时一并传到接口再进行后续处理。
1、ftl页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>个人店铺设置</title>
<link rel="stylesheet" href="xxx/css/shop-setting.css">
<script src="xxx/js/lib/require.js"></script>
</head>
<body>
<div>
<form id="setting-form" method="POST" enctype="multipart/form-data" role="form">
<div>
店铺名称:
<input type="text" id="shopName" name="shopName">
</div>
<div>
我的手机:
<input type="text" id="userMobile" name="userMobile">
</div>
<div>
我的头像:
<img src="xxx" id="headPicture" alt="头像图片">
<input type="file" id="chooseHeadPicture">
</div>
<div>
微信二维码:
<img src="xxx" id="wechatPicture" alt="微信二维码图片">
<input type="file" id="chooseWechatPicture">
</div>
<div>
<button type="button" id="submit">提交</button>
</div>
</form>
</div>
<script src="xxx/js/personalShop/edit.js"></script>
</body>
</html>
这里注意在form中使用enctype ="multipart/form-data",来使请求头的contentType=multipart/form-data
2、edit.js
...
$(function(){
var edit = {
init : function(){
this.checkInput();
this.submitEdit();
},
checkInput:function(){
$("#setting-form").validate({
rules:{
shopName:{
required:true,
maxlength:30,
},
userMobile:{
required:true,
maxlength:30,
},
},
messages:{
shopName:{
required:"必填项",
maxlength:"最多输入30个字符",
},
userMobile:{
required:"必填项",
maxlength:"最多输入30个字符",
},
}
});
$("#chooseHeadPicture").on("change",function () {
var path = $(this).val();
var imgType = path.substring(path.lastIndexOf(".")).toLowerCase();
var headPicSrc = window.URL.createObjectURL(this.files[0]);
var imgSize = this.files[0].size;
var id = $("#headPicture");
edit.checkPicture(imgType,imgSize,headPicSrc,id);
});
$("#chooseWechatPicture").on("change",function(){
var path = $(this).val();
var imgType = path.substring(path.lastIndexOf(".")).toLowerCase();
var headPicSrc = window.URL.createObjectURL(this.files[0]);
var imgSize = this.files[0].size;
var id = $("#wechatPicture");
edit.checkPicture(imgType,imgSize,headPicSrc,id);
});
},
//检查图片格式及大小
checkPicture :function(imgType,imgSize,src,id){
if (!imgType.match(/.jpg|.jpeg|.gif|.png|.bmp/)) {
//alert("图片格式必须为jpg,jpeg,gif,png或bmp");
return;
} else if(imgSize/1024/1024 > 1){
//alert("图片不允许大于1M");
return;
}else {
//当图片符合要求,使其在页面上展示
id.attr("src", src);
}
},
submitEdit:function () {
$("#submit").click(function () {
var formData = new FormData();
formData.append("shopName",$.trim($("#shopName").val()));
formData.append("userMobile",$.trim($("#userMobile").val()));
if($("#chooseHeadPicture").val()){
formData.append("headPicture",$("#chooseHeadPicture")[0].files[0]);
}
if($("#chooseWechatPicture").val()){
formData.append("wechatPicture",$("#chooseWechatPicture")[0].files[0]);
}
$.ajax({
url:'xxx/personalShop/editPersonalShopInfo',
//jQuery参数,默认为false,当设置为true的时候,ajax提交的时候不会序列化data,而是直接使用data
processData: false,
//避免jQuery对contentType进行操作,从而与<form>中的enctype="multipart/form-data产生冲突
contentType: false,
//上传文件不需要缓存
cache: false,
type:"POST",
data:formData,
success:function (data) {
}
})
});
}
};
edit.init();
})
这里使用FormData对象处理文本、文件等数据然后发Ajax请求,Ajax发送的数据也是formData。
FormData也类似json键值对的形式,关于FormData更多介绍可参考:FormData对象的使用
关于contentType的介绍可以参考:Ajax 请求头中常见content-type
3、controller层
PresonalShopController.java
...
@Controller
@RequestMapping(value="/xxx/personalShop")
public class PersonalShopController {
@RequestMapping("/edit")
public Response edit(EditPersonalShoptRequest request){
...
}
}
EditPersonalShopRequest.java
...
public class EditPersonalShoptRequest {
/**
* 店铺名称
*/
private String shopName;
/**
* 我的手机
*/
private String userMobile;
/**
* 头像
*/
private MultipartFile headPicture;
/**
* 我的微信
*/
private MultipartFile wechatPicture;
...set/get
}
接口的入参还是写的一个对象,只要把文件类型用MultipartFile定义,当Ajax请求时,同样会把js文件中定义的formData和controller的入参关联映射。这样做的好处就是当把入参封装成一个对象,当需要传的值很多时controller看起来也比较简洁。
注意:
- formData.append("shopName",$.trim($("#shopName").val()));中"shopName"要与controller入参中private String shopName一致,否则无法正常映射;
- controller入参前不需要@RequestBody来注解,因为http请求中contentType=multipart/form-data而不是application/json;
当然controller入参也可以分开来写:
PresonalShopController.java
...
@Controller
@RequestMapping(value="/xxx/personalShop")
public class PersonalShopController {
@RequestMapping("/edit")
public Response edit(@RequestParam(name = "shopName") String shopName,
@RequestParam(name = "userMobile") String userMobile,
@RequestParam(name = "headPicture", required = false) MultipartFile headPicture,
@RequestParam(name = "weChatPicture", required = false) MultipartFile weChatPicture){
...
}
}