赞
踩
在application.properties配置文件中设置文件上传属性
#是否开启文件上传支持,默认是true
spring.servlet.multipart.enabled=true
#文件写入磁盘的阈值,默认是0
spring.servlet.multipart.file-size-threshold=0
#单个文件的最大值,默认是50MB
spring.servlet.multipart.max-file-size=50MB
#多个文件上传时的总大小 值,默认是100MB
spring.servlet.multipart.max-request-size=100MB
#是否延迟解析,默认是false
spring.servlet.multipart.resolve-lazily=false
#自定义文件访问路径
myfile.path=C:\\File
本项目采用Maven方式,导入代码后,如有代码报错,在IDEA中按“Alt+Enter”可导入所需要的依赖包
// controller package com.SpringBoot.SpringStudy.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; @Slf4j @RestController public class FileController { @Value("${myfile.path}") private String filePath; // 单文件上传功能 @RequestMapping(value = "/uploadSingleFile", produces = "application/json;charset=utf-8") public String uploadSingleFile(@RequestParam("file") MultipartFile multipartFile) { String info = null; String fileName = multipartFile.getOriginalFilename(); File file = new File(filePath + '\\' + fileName); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); info = ("父级文件目录不存在,已创建目录"); } try { multipartFile.transferTo(file); } catch (IOException e) { info = ("程序错误,请重新上传" + e); e.printStackTrace(); } finally { info = ("文件上传成功,文件全路径名称为:{}" + file.getPath()); } return info; } // 多文件上传功能实现 @PostMapping("/uploadMultipleFile") public String uploadMultipleFile(@RequestParam("file") MultipartFile[] multipartFiles) { String info = null; for (MultipartFile multipartFile : multipartFiles) { String fileName = multipartFile.getOriginalFilename(); File file = new File(filePath + '\\' + fileName); if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); info = ("父级文件目录不存在,已创建目录"); } try { multipartFile.transferTo(file); } catch (IOException e) { info = ("程序错误,请重新上传" + e); e.printStackTrace(); } finally { info = ("文件上传成功,文件全路径名称为:" + file.getPath()); } } return info; } }
SpringBoot采用了MultipartFile工具类,相关接口介绍如下
// MultipartFile工具类 package org.springframework.web.multipart; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import org.springframework.core.io.InputStreamSource; import org.springframework.core.io.Resource; import org.springframework.lang.Nullable; import org.springframework.util.FileCopyUtils; public interface MultipartFile extends InputStreamSource { // 返回参数的名称 String getName(); //获取源文件的昵称 @Nullable String getOriginalFilename(); // 返回文件的内容类型 @Nullable String getContentType(); // 判断上传的文件是否为空 boolean isEmpty(); // 以字节为单位返回文件大小 long getSize(); / 将文件内容转化成byte[] 并返回 byte[] getBytes() throws IOException; //getInputStream() 返回InputStream读取文件的内容 InputStream getInputStream() throws IOException; default Resource getResource() { return new MultipartFileResource(this); } //transferTo是复制file文件到指定位置(比如D盘下的某个位置),不然程序执行完,文件就会消失,程序运行时,临时存储在temp这个文件夹中 void transferTo(File var1) throws IOException, IllegalStateException; default void transferTo(Path dest) throws IOException, IllegalStateException { FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest)); } }
// vue.config.js const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, lintOnSave: false,//关闭语法检查 devServer: { host: 'localhost', port: 8888, open: false, proxy: { '/api': { target: 'http://localhost:8080',// 后台接口域名 ws: true,//如果要代理 websockets,配置这个参数 secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true,//是否跨域 pathRewrite: { '^/api': '' } } } } })
npm install axios
配置main.js文件
// main.js import { createApp } from 'vue' import App from './App.vue' import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' import * as ElementPlusIconsVue from '@element-plus/icons-vue' import router from './router' import store from './store' // 引入axios import axios from 'axios' // 设置defaults.baseURL axios.defaults.baseURL='/api' const app = createApp(App) for (const [key, component] of Object.entries(ElementPlusIconsVue)) { app.component(key, component) } app.use(store).use(router).use(ElementPlus).mount('#app') // 全局应用axios app.config.globalProperties.$http = axios
配置好main.js和vue.config.js可创建组件实现文件上传,具体上传方式下面分为传统文件上传方式和el-upload方式进行详细介绍
el-upload文件上传相关配置可参考Element Plus官方文档
/uploadMultipleFile对应SpringBoot Controller当中的方法,需要在前面加上“api”以便于proxy解析代理
<script setup> import {UploadFilled} from '@element-plus/icons-vue' import {getCurrentInstance} from "vue"; const {proxy} = getCurrentInstance() // 设置上传url let fileUrl = "api/uploadMultipleFile" function uploadFiles() { proxy.$refs.upload.submit() } </script> <template> <h1>el-upload文件上传</h1> <el-upload ref="upload" class="upload-demo" drag :action="fileUrl" multiple :auto-upload="false" list-type="picture" > <el-icon class="el-icon--upload"> <upload-filled/> </el-icon> <div class="el-upload__text"> Drop file here or <em>click to upload</em> </div> <template #tip> <div class="el-upload__tip"> jpg/png files with a size less than 500kb </div> </template> </el-upload> <el-button type="primary" @click="uploadFiles">上传</el-button> </template>
在传统文件上传中介绍了“单文件上传”、“文件夹上传”和拖拽上传方式,下面分别采用了xhr方式和axios两种方式实现文件上传,代码如下
<script setup> import {getCurrentInstance, reactive, ref} from "vue"; const {proxy} = getCurrentInstance() const fd = new FormData(); const percentage = ref(0) function onmouseover(e) { // 阻止默认事件 e.preventDefault() e.stopPropagation() // 拖拽时禁用页面内容选取 document.onselectstart = function () { return false } } function dragenter(e) { // 阻止默认事件 e.preventDefault() e.stopPropagation() } function dragover(e) { // 阻止默认事件 e.preventDefault() e.stopPropagation() // console.log(e) } /** * 清除FormData **/ function clearFormData(fd) { fd.forEach(function (value, key) { fd.delete(key); }) } /** * 进度条颜色控制 **/ function customColorMethod(percentage) { if (percentage < 30) { return '#909399'; } else if (percentage < 70) { return '#e6a23c'; } else { return '#67c23a'; } } /** * 进度条 **/ let onUploadProgress = (progressEvent) => { const {loaded, total} = progressEvent; let progress = Math.round((loaded / total) * 100) percentage.value = progress console.log(`Upload Progress: ${progress}%`); } function change(e) { clearFormData(fd) fd.append('file', e.target.files[0], e.target.files[0].name) uploadFile(fd) } function uploadFile(fd) { /**axios方式**/ proxy.$http.post("/uploadMultipleFile", fd, { headers: { 'Content-Type': 'multipart/form-data', }, onUploadProgress }).then(data => { if (data.status !== 200) proxy.$message.error(data.data) proxy.$message.success(data.data) }) /**xhr方式**/ /* // 1.创建xhr var xhr = new XMLHttpRequest(); // 2.创建请求 let url = "api/uploadSingleFile" xhr.open("POST", url); // 3.发起请求 xhr.send(fd); xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { if (xhr.status === 200) { // 上传成功 proxy.$message.success('上传成功') } else { // 上传失败 console.log('图片上传失败!' + xhr.responseText) } } }*/ } /** * 拖拽方法 **/ function drop(e) { e.preventDefault() e.stopPropagation() console.log(e) clearFormData(fd) for (let item of e.dataTransfer.items) { const entry = item.webkitGetAsEntry() upload(entry) } // proxy.$http.post("/uploadSingleFile", fd).then(data => { // console.log(data) // }) // 1.创建xhr } function upload_a() { uploadFile(fd) } /** * 判断是文件还是目录 **/ function upload(entry) { if (entry.isDirectory) { // 目录 const reader = entry.createReader() reader.readEntries(entries => { for (const entry of entries) { upload(entry) } }) } else { // 文件 entry.file(f => { console.log('文件', f) fd.append('file', f, f.name) }) } } </script> <template> <h1>经典文件上传</h1> <!-- 添加multiple属性实现多个文件上传--> <input type="file" multiple @change="change"> <input type="file" webkitdirectory mozdirectory odirectory> <div class="uploadArea" ref="dragArea" @dragenter="dragenter" @dragover="dragover" @drop="drop" @change="change" @mouseover="onmouseover"> <UploadFilled class="icon"/> <p style="color: #409EFF">文件拖拽上传区域</p> </div> <el-progress :text-inside="true" :stroke-width="24" :percentage="percentage" :color="customColorMethod"></el-progress> <el-button type="primary" @click="upload_a">上传</el-button> </template> <style scoped> .uploadArea { color: #A8ABB2; margin-top: 2%; height: 200px; background: #FAFAFA; border: #DCDFE6 1px dashed; border-radius: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; box-sizing: border-box; } div .uploadArea:hover { border: #409EFF 2px dashed; } p { cursor: default; } .el-button { margin-top: 2%; } .el-progress { margin-top: 1%; } .icon { width: 80px; height: 80px; //box-sizing: border-box; } </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。