Vue + Springboot 文件上传项目笔记(一)
Vue + Springboot 文件上传项目笔记(一)
前端
- 使用脚手架创建项目
vue create vue_fileuploaddemo
- 等待命令执行完毕
- 添加 element-ui 组件
E:\java\idea_java_maven\vue_fileuploaddemo>yarn add element-ui
yarn add v1.22.19
[1/4] Resolving packages...
warning element-ui > async-validator > babel-runtime > core-js@2.6.12: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
[2/4] Fetching packages...
[3/4] Linking dependencies...
warning " > element-ui@2.15.13" has incorrect peer dependency "vue@^2.5.17".
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 8 new dependencies.
info Direct dependencies
└─ element-ui@2.15.13
info All dependencies
├─ async-validator@1.8.5
├─ babel-helper-vue-jsx-merge-props@2.0.3
├─ babel-runtime@6.26.0
├─ element-ui@2.15.13
├─ normalize-wheel@1.0.1
├─ regenerator-runtime@0.11.1
├─ resize-observer-polyfill@1.5.1
└─ throttle-debounce@1.1.0
Done in 26.77s.
- 添加 element-plus 组件
E:\java\idea_java_maven\vue_fileuploaddemo>yarn add element-plus
yarn add v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
warning " > element-ui@2.15.13" has incorrect peer dependency "vue@^2.5.17".
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 18 new dependencies.
info Direct dependencies
└─ element-plus@2.3.4
info All dependencies
├─ @ctrl/tinycolor@3.6.0
├─ @element-plus/icons-vue@2.1.0
├─ @floating-ui/core@1.2.6
├─ @floating-ui/dom@1.2.8
├─ @popperjs/core@2.11.7
├─ @types/lodash-es@4.17.7
├─ @types/lodash@4.14.194
├─ @types/web-bluetooth@0.0.16
├─ @vueuse/core@9.13.0
├─ @vueuse/metadata@9.13.0
├─ @vueuse/shared@9.13.0
├─ async-validator@4.2.5
├─ dayjs@1.11.7
├─ element-plus@2.3.4
├─ lodash-es@4.17.21
├─ lodash-unified@1.0.3
├─ memoize-one@6.0.0
└─ normalize-wheel-es@1.2.0
Done in 44.53s.
- 还要添加 axios 组件和 vue-axios 但是因为没有记录
- 命令
yarn add axios
yarn add vue-axios
- 注意这里是 add 而 不是 install
E:\java\idea_java_maven\vue_fileuploaddemo>yarn add axios
E:\java\idea_java_maven\vue_fileuploaddemo>yarn add vue-axios
- 在 main.js 中添加
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus';
import 'element-plus/theme-chalk/index.css';
import locale from 'element-plus/lib/locale/lang/zh-cn'
import 'element-ui/lib/theme-chalk/index.css';createApp(App).use(router).use(ElementPlus, { locale }).mount('#app')
- 新使用 yarn 来管理包
- 安装 依赖包
yarn install
- 编译和热加载用于开发
- 命令行启动项目
yarn serve
- 编译和最小化产品
- 输出 可用的index.html 项目
yarn build
主要代码
- 使用 element-ui 来创建页面的部分
<div class="UploadFile" style="border:solid blue 1px;"><el-upload class="upload-demo" action="http://127.0.0.1:14852/file/uploadandownload" :on-preview="upload"accept=".jpg" :limit="10"><!-- 回调函数--><el-button size="small" type="primary">点击上传</el-button><div class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div></el-upload>
</div>
// 回调函数
methods: {upload(file) {alert("文件上传.........");alert(file.response.url);const url = file.response.url;window.open(url);}
后端
- 使用 idea 创建 springboot 项目
- 配置 application.yml
spring:servlet:multipart:max-file-size:100MBapplication:name: SpringbootFileUploadDemodatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3307/FileUploadDemo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=trueusername: rootpassword: admin
server:port: 14852undertow:io-threads: 16worker-threads: 256buffer-size: 1024buffers-per-region: 1024direct-buffers: trueservlet:context-path: /
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.codervibe.springbootfileuploaddemo.model# 日志
logging:level:# 将 包 内 设置为 info # mapper 包 中设置为 debugroot: infocom.codervibe.springbootfileuploaddemo: infocom.codervibe.springbootfileuploaddemo.mapper: debugfile:path: ./log
- 配置 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.6.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.codervibe</groupId><artifactId>SpringbootFileUploadDemo</artifactId><version>0.0.1-SNAPSHOT</version><name>SpringbootFileUploadDemo</name><description>SpringbootFileUploadDemo</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.2</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version><scope>provided</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.21</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 排除Tomcat依赖 --><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><!-- 添加 Undertow依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency></dependencies><build><finalName>Springboot_FileUploadDemo</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
- 创建返回的 Response
package com.codervibe.springbootfileuploaddemo.model;/*** @author Administrator*/
public class Resp <E>{private String code;private String message;private E body;public Resp(String code, String message, E body) {this.code = code;this.message = message;this.body = body;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public E getBody() {return body;}public void setBody(E body) {this.body = body;}// 成功的时候 返回值为200public static <E> Resp<E> success(E body){return new Resp<>("200","",body);}// 失败的时候 返回值由调用的时候指定public static <E> Resp<E> fail(String code,String message){return new Resp<>(code,message,null);}
}
- 上传文件的接口
package com.codervibe.springbootfileuploaddemo.controller;import com.codervibe.springbootfileuploaddemo.model.Resp;
import com.codervibe.springbootfileuploaddemo.service.FileUploadService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;/*** @author Administrator* 文件上传接口*/
@RestController
@CrossOrigin
@RequestMapping(value = "/file")
public class FileUploadController {@Resourceprivate FileUploadService fileUploadService;private Log log = LogFactory.getLog(this.getClass());private SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMddHHmmss");@RequestMapping(value = "/upload", method = RequestMethod.POST)private Resp<String> upload(@RequestParam("file") MultipartFile file) {log.info("上传文件 方法 执行");return fileUploadService.fileUpload(file);}//实际上这只是 上传之后 显示文件内容 并没有办法下载@RequestMapping(value = "/uploadandownload", method = RequestMethod.POST)private Map<String,Object> uploadandownload(@RequestParam("file") MultipartFile file, HttpServletRequest request) {// 这里的大部分内容应该写在 service 层的实现中log.info("上传下载 文件 方法 执行");Map<String,Object> result =new HashMap<>();String originalFilename = file.getOriginalFilename();String 当前时间 = timeFormat.format(new Date());String realPath = request.getServletContext().getRealPath("/") + 当前时间;log.info("realPath = "+realPath);File folder =new File(realPath);if (!folder.exists()) {folder.mkdirs();}String newName = UUID.randomUUID()+"."+originalFilename.substring(originalFilename.lastIndexOf(".") + 1);log.info("newName = "+newName);File realfile =new File(folder,newName);try {file.transferTo(realfile);String url = request.getScheme()+"://"+request.getServerName() + ":"+request.getServerPort() +"/"+当前时间 + newName;log.info("url="+url);result.put("code",200);result.put("url",url);}catch (IOException e) {result.put("code",400);result.put("message",e.getMessage());}boolean fileExists = realfile.exists();if (fileExists) {log.info("文件存在 文件保存成功");} else {log.warn("文件不存在 文件保存失败!");}return result;}
}
- service层 接口 以及 service 接口的 实现
- service层 接口
package com.codervibe.springbootfileuploaddemo.service;import com.codervibe.springbootfileuploaddemo.model.Resp;
import org.springframework.web.multipart.MultipartFile;/*** @author Administrator*/
public interface FileUploadService {/*** 文件上传*/Resp<String> fileUpload(MultipartFile file);
}
- service 接口 实现
package com.codervibe.springbootfileuploaddemo.service.Impl;import com.codervibe.springbootfileuploaddemo.model.Resp;
import com.codervibe.springbootfileuploaddemo.service.FileUploadService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;/*** @author Administrator*/
@Service
public class FileUploadServiceImpl implements FileUploadService {Log log = LogFactory.getLog(this.getClass());SimpleDateFormat timeFormatForSendingMail = new SimpleDateFormat("yyyyMMddHHmmss");/*** 文件上传*/@Overridepublic Resp<String> fileUpload(MultipartFile file) {log.info("文件上传服务.......");if (file.isEmpty()) {return Resp.fail("400", "文件为空");}String OriginalFileName = file.getOriginalFilename();String 当前时间 = timeFormatForSendingMail.format(new Date());log.info("当前时间: "+当前时间);log.info("原本的文件名:"+ OriginalFileName);String 文件名 = OriginalFileName.substring(0,OriginalFileName.indexOf("."));String fileName = 当前时间 + 文件名 +"."+ OriginalFileName.substring(OriginalFileName.lastIndexOf(".") + 1);// 存储的位置写死了 如果要修改 还要重新编译 就有些麻烦String filePath = "C:\\Users\\Default\\AppData\\Local\\FileUploadDemo\\";log.info("filePath" + filePath);log.info("保存的文件名:"+ 文件名);log.info("文件保存位置:" + filePath + fileName);File newFile = new File(filePath + fileName);if (!newFile.getParentFile().exists()) {newFile.getParentFile().mkdirs();}try {file.transferTo(newFile);} catch (Exception e) {e.printStackTrace();return Resp.fail("500",OriginalFileName + "上传失败");}boolean fileExists = newFile.exists();if (fileExists) {log.info("文件存在 文件保存成功");} else {log.warn("文件不存在 文件保存失败!");}return Resp.success(fileName);}
}
前端项目地址 https://github.com/codervibe/vue_fileuploaddemo.git
后端项目地址 https://github.com/codervibe/SpringbootFileUploadDemo.git