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:100MB
application:
name: SpringbootFileUploadDemo
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/FileUploadDemo?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true
username: root
password: admin
server:
port: 14852
undertow:
io-threads: 16
worker-threads: 256
buffer-size: 1024
buffers-per-region: 1024
direct-buffers: true
servlet:
context-path: /
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.codervibe.springbootfileuploaddemo.model
# 日志
logging:
level:
# 将 包 内 设置为 info
# mapper 包 中设置为 debug
root: info
com.codervibe.springbootfileuploaddemo: info
com.codervibe.springbootfileuploaddemo.mapper: debug
file:
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;
}
// 成功的时候 返回值为200
public 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 {
@Resource
private 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");
/**
* 文件上传
*/
@Override
public 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