今天在写SpringBoot+vue修改商品信息的功能,遇到一些问题,问题可以说是一环套一环。
首先是上传图片,vue+springboot的上传图片并不是很复杂。
前端VUE:
先说前端,fromdata二进制形式传递选中图片至后端springboot,代码如下:
<form role="form" enctype="multipart/form-data">
<input type="file" name="upload" id="goodsImg">
<input type="text" id="gname" name="gname" v-model.laze:value="goods.gname">
<button type="button" @click="updateGoods()">更新</button>
</from>
// vue 中使用 window.FormData(),否则会报 'FormData isn't definded'
let formData = new window.FormData();
export default {
data() {
return {
goods: {
gname: "",
isSale: "上架"
}
}
},
methods: {
updateGoods() {
// 'file' 这个名字要和后台获取文件的名字一样;
formData.append('file', document.getElementById("goodsImg").files[0]);
//goodsStr 也要和后台接收的参数名一样,否则会报400
formData.append('goodsStr', JSON.stringify(this.goods));
this.$axios({
url: XXXX,
data: formData,
method: 'put',
headers: {
'Content-Type': 'multipart/form-data',
}
}).then((res) => {
location.reload();
}) // 发送请求
}
}
}
其中,this.goods中的数据均为普通数据,与file一同以formdata的形式提交到后台,其中gname为普通字符串,而sSale为枚举类型。
后端SpringBoot
后台springboot接收fromdata数据,代码如下:
public void uploadWork(HttpServletRequest request,
@RequestParam(value = "file", required = false) MultipartFile file, @RequestParam String goodsStr) throws Exception {
request.setCharacterEncoding("UTF-8");
if (file != null) {
//获取项目实际发布的路径
String uploadPath = request.getSession().getServletContext().getRealPath("/") + "uploads\\";
//获取上传文件的文件名
String filename = file.getOriginalFilename();
//获得当前时间戳,头像上传文件名使用电话号码和当前时间戳表示
long day = new Date().getTime();
String uploadFilename = uploadPath + filename;
//保存
try {
File uploadFile = new File(uploadFilename);
//查询上传地址的父路径是否存在
if (!uploadFile.getParentFile().exists()) {
//如果不存在,创建该文件
uploadFile.getParentFile().mkdirs();
}
//写入文件
file.transferTo(uploadFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}
写到这里,上传文件算是结束了,但是遇到了一个问题,就是@RequestParam String goodsStr,获取到的参数是字符串,还是json格式的字符串。之前一般是使用fastjson类将json字符串转成javaBean对象,但是使用fastjson转json字符串,又遇到了一个问题就是,isSale字段他是一个enmu枚举对象,从前台获取的字符是不能直接转化为枚举对象的。
由于@JsonValue注解是在,jackson类对javaBean对象进行序列化是返回的,反推,那么相应的jackson类在对json字符串进行解析时,就会返回原来的枚举类型。抱着试试的心态,将后台代码进行了补充:
@PutMapping("/xxx)
public void uploadWork(HttpServletRequest request,
@RequestParam(value = "file", required = false) MultipartFile file, @RequestParam String goodsStr) throws Exception {
request.setCharacterEncoding("UTF-8");
//jackson对json字符串进行解析
Goods goods = new ObjectMapper().readValue(goodsStr, Goods.class);
if (file != null) {
//获取项目实际发布的路径
String uploadPath = request.getSession().getServletContext().getRealPath("/") + "uploads\\";
//获取上传文件的文件名
String filename = file.getOriginalFilename();
//获得当前时间戳,头像上传文件名使用电话号码和当前时间戳表示
long day = new Date().getTime();
String fileName = goods.getGid() + "" + day + "." + filename.split("\\.")[1];
String uploadFilename = uploadPath + fileName;
//保存
try {
File uploadFile = new File(uploadFilename);
//查询上传地址的父路径是否存在
if (!uploadFile.getParentFile().exists()) {
//如果不存在,创建该文件
uploadFile.getParentFile().mkdirs();
}
//写入文件
file.transferTo(uploadFile);
//删除原有的该数据对于的图片
delectImg(goods.getGimg(), uploadPath);
goods.setGimg(fileName);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void delectImg(String goodsImg, String uploadPath) {
if (goodsImg != null && goodsImg != "") {
File fileImg = new File(uploadPath + "/" + goodsImg);
if (fileImg.exists()) {
fileImg.delete();
}
}
}
至此,包括上传图片,以及提交图片的同时提交普通数据,fromdata格式提交数据时,枚举的处理就已经全部处理完毕。