一、 UNIAPP前端文件上传demo
只要会阅读UNIAPP文档,我们会发现其实前端这块很好弄,只需要一个按钮,然后按钮下方呈现选择的图片即可。
但是我们还有几个细节需要注意。1、chooseimage接口成功后,返回的文件路径是一个数组,因此我们也应当使用一个数组来接收;2、顺利实现图片选择后,可以直接进行上传了,但是这里上传时,‘name’参数才是对应后端接口的文件类,并且上传时无需声明申请头,他会自动配置。
下面是前端代码:
<template>
<view class="content">
<view class="button">
<button @click="choose" value="请选择文件">请选择文件</button>
</view>
<view class="img" v-for="imgPath in imgPaths">
<image class="img_img" :src="imgPath"></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello',
imgPaths:[]
}
},
onLoad() {
},
methods: {
choose(e){
var me = this;
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function (res) {
me.imgPaths = res.tempFilePaths;
console.log(me.imgPaths);
uni.uploadFile({
url: 'http://192.168.1.106:8080/uploadImg', //仅为示例,非真实的接口地址
filePath: me.imgPaths[0],
name: 'uploadFile',
formData: {
'user': 'test'
},
success: (uploadFileRes) => {
console.log(uploadFileRes);
}
});
}
});
}
}
}
</script>
二、 后端文件处理demo
这里后端的接收有很多细节需要注意,可以说不注意的话简直是一步一个坑。至于有哪些细节,我们待下面再说,我们先说一下正确的过程和代码实现。
首先一个不用说的,我们自然是需要创建一个springboot项目,而后我们创建controller类,在其中编写上传图片的方法。方法中包括的上传过程主要有:① 获取MultipartFile类对象参数的原始文件名;② 获取该对象的后缀名;③ 重新命名文件(使用UUID防止文件名重复);④ 指定文件存储的硬盘地址;⑤ 利用MultipartFile对象的transferto方法,在磁盘中创建该文件(最好添加时间文件夹,方便区分);⑥ 写入磁盘中,最后如果成功上传则返回访问地址,否则返回其他相关数据。
最后不要忘记了配置相关信息,因为我们是将文件写在了磁盘中,所以我们访问时需要将路径映射到磁盘路径中去。这里我们在properties中写:
filePath=E:/Data/uploadFile
spring.resources.static-locations=classpath:static/**spring.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${filePath}
略微解释一下上述语句,filePath自然是指的我们文件上传的磁盘路径地址,而static-locations则是指定这些目录下的文件可直接访问,当这些目录中存在同名文件时,则根据优先级进行显示。当然也可以写配置类进行同样的操作。
好了,至此我们上controller中的上传方法吧。
SimpleDateFormat sd = new SimpleDateFormat("yyyy/MM/dd");
@PostMapping("/uploadImg")
public String uploadImg(MultipartFile uploadFile, HttpServletRequest req){
//获取文件名
String fileName = uploadFile.getOriginalFilename();
//获取文件后缀名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//重新生成文件名
fileName = UUID.randomUUID()+suffixName;
//添加日期目录
String format = sd.format(new Date());
//指定本地文件夹存储图片
String filePath = "E:/Data/uploadFile/"+format+"/";
File file = new File(filePath,fileName);
if (!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
try {
//将图片保存到static文件夹里
file.createNewFile();
uploadFile.transferTo(new File(filePath+fileName));
return "http://"+req.getRemoteHost()+":"+req.getServerPort()+"/"+format+"/"+fileName;
} catch (Exception e) {
e.printStackTrace();
return "false";
}
}
三、 常见问题总结
其实这里才是我的重头戏,我将对这个小demo中遇到所有问题及解决方案进行总结归纳。
1) 不可以将上传来的文件保存到项目地址中,即不可以保存在resource/static目录下,因为这样的话,及时上传成功,也需要重启整个项目才能够通过地址访问到该图片。换言之,target不会因为你上传了图片,就自动更新静态资源。
2) 配置文件中static-location后面配置的那些目录,就是localhost:8080可以直接访问的文件了,也就是说我们现在已经将磁盘的目录配置上了,那么我们存放在E:/Data/uploadFile文件夹中的任何文件就可以直接localhost:8080/文件名进行访问了。