行业知识
使用Vue+SpringBoot完成前端文件上传,后端接收保存
因为自己的毕业设计需要实现这一功能,所以在此记录一下。
我自己的毕设的系统的一个功能的小步骤就需要把前端上传的文件保存到后端,之后再操作,本人还没有学习SpringBoot所以踩了不少坑。
方法介绍
前端使用vue、以及el-upload组件、axios发送post请求。
前端:
{{ item.label }} {{ item.fileName === "" ? "点击上传文件" : item.fileName }} 移除 action属性为上传的地址,这里用#号忽略了
auto-upload为是否自动上传,设置为false,关闭自动上传;
show-file-list 是否显示已上传文件列表
before-upload 上传文件之前的钩子(可以不加,我用来加一些条件),参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
on-change 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
limit 上传文件最大数量
on-exceed 文件超出个数限制时的钩子
file-list 上传的文件列表,使用v-model双向数据绑定了一下
下面是两个按钮一个,默认具有上传功能(我也不知道为啥),所以移除的按钮加了stop阻止它弹出上传文件的框。
、
data中的代码
uploadParam2: [ {label: "xx数据", fileName: "", files: []}, {label: "xx数据", fileName: "", files: []}, ] mathodes:
最主要的函数
handlerUploadChange(file,index,num,label){ let url=null; let layername=null; const formData = new FormData();//这里的key是后端形参接收变量用的//file.raw才是我们要得文件,不理解的话自己可以console.log(file)看一下就知道了 formData.append('file', file.raw);//发送请求去后端,但是有人说要设置请求头//我没有设置但是成功了,请求头自动变了,如果没变的话自己加一下 axios.post('/hhh/export/upload',formData).then(response => { // 文件上传成功处理逻辑 let data =response.data; url=data.url; layername=data.layerName; if(label === 'xx数据'){ this.$refs.map_res.addResult1(url,layername); this.showable1= !this.showable1; }else if(label === 'xxx数据'){ this.$refs.map_res.addResult2(url,layername); this.showable2=!this.showable2; } }) } if中的是我自己的功能不用管,当点击第一个按钮时,加载一个图层,点另一个加载另一个图层。
最重要的是发送请求去后端,有的教程说发送请求要设置请求头,因为要发送文件,如果设置的话axios的post方法加上一个参数{ headers: { 'Content-Type': 'multipart/form-data' } }
只要文件状态改变,就会调用这个函数,发送请求去后端,因为涉及到跨域问题请在vue.config中配置代理:我的vue再8080端口,后端在8081端口,大家自行修改
devServer: { proxy: { //以/hhh开始的路径都走这个代理 '/hhh': { target: 'http://localhost:8081', //重写路径,将/hhh删除 pathRewrite: {'^/hhh': '/'}, changeOrigin: true//改变起源,让对方服务器不知道我们的起源 } } } 后端代码:
springboot项目如何搭建我就不说了,不会的去搜一下
重点,前端我们新建一个FormDate格式的对象,将文件append进去了,在springboot3中我们要使用MultipartFile接口来接收前端传过来文件,将这个文件通过@RequestParam("file")注解映射到形参上,message对象是我自己建的一个pojo类,为了返回给浏览器一些信息,来便于我自己操作的。
import com.nlg.TRSH.pojo.Message;import com.nlg.TRSH.utils.GeoServerUtil;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;@RestController@CrossOrigin(origins = "http://localhost:8080")@RequestMapping("/export")public class UpdateLoadController { private static String UPLOAD_PATH="D:\dev\土壤酸化存储数据\"; @PostMapping("/upload") public Message upload(@RequestParam("file") MultipartFile file ,HttpServletRequest request, HttpServletResponse response) throws IOException { String savepath = null; //设置响应编码方式,防止中文乱码 response.setHeader("Content-type", "application/json;charset=UTF-8"); Message message = new Message(); try { String Filename = null; if (!file.isEmpty()) { Filename = file.getOriginalFilename(); } var path = UPLOAD_PATH + Filename; System.out.println(path);//这一行代码就是保存到指定路径,使用的是接口里的方法很方便 file.transferTo(new File(path)); message.setStatus("success"); message.setMessage("保存成功"); int lastDotIndex = Filename.lastIndexOf('.'); // 查找最后一个点的位置 String layername = Filename.substring(0, lastDotIndex); // 获取去除后缀的文件名//从这开始不用看,上面已经保存完了,代码是我自己封装的一些工具类 boolean exist = GeoServerUtil.judgeWorkSpace("nlg"); String phstore = "ph" + System.currentTimeMillis(); GeoServerUtil.shpJudgeDatabase("nlg",phstore,path,layername,"ph"); message.setUrl("http://localhost:8088/geoserver/nlg/wms"); layername="nlg:"+layername; message.setLayerName(layername); } catch (Exception e) { e.printStackTrace(); }//返回给前端message对象 return message; }}