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 " > [email protected]" 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 " > [email protected]" 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文件,且不超过500kbdiv>
      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

<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.0modelVersion>
    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.2.6.RELEASEversion>
        <relativePath/> 
    parent>
    <groupId>com.codervibegroupId>
    <artifactId>SpringbootFileUploadDemoartifactId>
    <version>0.0.1-SNAPSHOTversion>
    <name>SpringbootFileUploadDemoname>
    <description>SpringbootFileUploadDemodescription>
    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <maven.compiler.source>1.8maven.compiler.source>
        <maven.compiler.target>1.8maven.compiler.target>
    properties>
    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.11version>
            <scope>testscope>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>2.1.2version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.18.22version>
            <scope>providedscope>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>8.0.28version>
        dependency>
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
            <version>1.1.21version>
        dependency>
        <dependency>
            <groupId>org.junit.jupitergroupId>
            <artifactId>junit-jupiterartifactId>
        dependency>

        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>1.2.17version>
        dependency>


        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
            
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-starter-tomcatartifactId>
                exclusion>
            exclusions>
        dependency>

        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-undertowartifactId>
        dependency>

    dependencies>

    <build>
        <finalName>Springboot_FileUploadDemofinalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>

            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            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

你可能感兴趣的:(JAVA,WEB,Vue,前后端分离,vue.js,spring,boot,笔记)