JavaWeb学习:Vue+Element-plus实现文件上传

需求:

JavaWeb的购物车系统需要实现新增商品的功能。商品的展示图片需要与商品的基础信息一同上传至服务器,图片保存路径则随基础信息异同保存至数据库。

实现:

前端:

1. 选择相应的文件上传组件:

选择点击按钮手动上传的组件,源代码如下:

javascript 复制代码
<template>
  <el-upload
    ref="uploadRef"
    class="upload-demo"
    action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
    :auto-upload="false"
  >
    <template #trigger>
      <el-button type="primary">select file</el-button>
    </template>

    <el-button class="ml-3" type="success" @click="submitUpload">
      upload to server
    </el-button>

    <template #tip>
      <div class="el-upload__tip">
        jpg/png files with a size less than 500kb
      </div>
    </template>
  </el-upload>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import type { UploadInstance } from 'element-plus'

const uploadRef = ref<UploadInstance>()

const submitUpload = () => {
  uploadRef.value!.submit()
}
</script>

后端MultipartFile对应的是前端FormData数据,为成功上传至后端,需要对上传过程进行一些修改,将自定义的上传过程编写在before-upload周期中,返回值为false则不会调用默认的上传方法

javascript 复制代码
<template>
    <el-upload
      ref="uploadRef"
      class="upload-demo"
      action="http://localhost:8090/img/upload"
      :auto-upload="false"
      :name="file"
      :before-upload="handleBeforeUpload"
      @change="handleChange"
      :limit="1"
    >
      <template #trigger>
        <el-button type="primary">select file</el-button>
      </template>
      <el-button class="ml-3" type="success" @click="submitUpload">
        upload to server
      </el-button>
    </el-upload>
  </template>
  
  <script  setup>
  import { ref } from 'vue'
  import axios from 'axios'
  const uploadRef = ref()
  
  const submitUpload = () => {
    uploadRef.value.submit()
  }
  const file = ref()
  const handleChange = (e) => {
    file.value = e.file; // 获取到的文件对象
  // ...
};
  const handleBeforeUpload = async (file) => {
    // 使用axios发送文件前,确保创建FormData实例
    const formData = new FormData();
    formData.append('file', file);
    for (let pair of formData.entries()) {
      console.log(pair[0] + ', ' + pair[1]);
    }
    // 配置axios请求
    axios({
      method: 'post',
      url: 'http://localhost:8090/img/upload',
      // 上传数据直接为formData实例即可,无需通过JSON封装,否则无法解析!!!
      data: formData,
      headers: { 'Content-Type': 'multipart/form-data' }
    })
      .then(response => {
        console.log(response);
      })
      .catch(error => {
        console.log(error);
      });
      return false;
  }
  </script>

FormData类型的数据无法直接在控制台中log出来,直接log会生成空对象{},用遍历方式便可输出FormData中保存的对象 。

上传数据data直接为formData实例即可,无需通过JSON封装,否则后端无法解析!!!

上传文件一定是POST请求,所以后端也是用@RequestBody注解解析请求数据

部分upload组件传入的属性含义如下:

action:文件上传的请求

auto-upload:文件导入后是否自动上传

limit:限制文件上传的个数

后端:

1. 配置解析器

java 复制代码
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.web.multipart.commons.CommonsMultipartResolver;  
import org.springframework.web.multipart.MultipartResolver;  
  
@Configuration  
public class WebMvcConfig {  
    @Bean
    public MultipartResolver multipartResolver() {
        // 使用StandardServletMultipartResolver作为MultipartResolver实现
        StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
        // 可以进一步配置其他属性,例如文件大小限制等,但通常这些在web.xml或通过@MultipartConfig注解在Servlet上进行配置
        return multipartResolver;
    }
}

2. 在启动器中初始化解析器的相关信息

配置MultiPartConfigElement这一步很重要!!!因为缺了这一步所以卡了一整天555

具体可参考官方文档:StandardServletMultipartResolver (Spring Framework 6.1.8 API)

java 复制代码
    /**
     * 自定义Servlet注册时的配置,特别是针对文件上传的配置。
     * 此方法设置上传文件的存储位置、最大文件大小、最大请求大小和文件大小阈值。
     *
     * @param registration Servlet注册的动态对象,允许在注册时进行额外的配置。
     */
    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        // 设置多部分配置元素,包括文件上传的临时存储路径、最大文件大小、最大请求大小和写入磁盘的阈值。
        registration.setMultipartConfig(new MultipartConfigElement("D:\\coding\\javawebcoding\\javaweb_official_page\\src\\main\\webapp\\img", 1024 * 1024 * 10, 1024 * 1024 * 50, 1024 * 1024));
    }

3. 配置处理图片上传请求的controller类及handler方法

java 复制代码
@RestController
@CrossOrigin(origins = "http://localhost:5173")
// 对解析器进行相关配置
@MultipartConfig(maxFileSize = 1024 * 1024 * 10, maxRequestSize = 1024 * 1024 * 50)
public class FileController {
    // 文件保存路径:webapp/img
    private static final String UPLOAD_DIR = "D:\\coding\\javawebcoding\\javaweb_official_page\\src\\main\\webapp\\img"; // 图片保存的目录相对路径
    /**
     * 处理图片上传请求。
     *
     * @param file 用户上传的图片文件,以MultipartFile形式接收。
     * @return 返回一个Result对象,包含上传结果的状态和消息。
     *         如果上传成功,返回包含成功消息和文件名的结果;
     *         如果上传失败,返回包含失败原因的结果。
     */
    @RequestMapping("/img/upload")
    public Result handleImageUpload(@RequestBody MultipartFile file) {
        // 检查上传的文件是否为空
        if (file == null || file.isEmpty()) {
            return Result.failed("图片上传失败:" + "图片为空");
        }
        try {
            // 读取上传文件的字节
            byte[] bytes = file.getBytes();
            // 构建保存路径
            Path path = Paths.get(UPLOAD_DIR + File.separator + file.getOriginalFilename());
            // 将文件字节写入指定路径
            Files.write(path, bytes);

            return Result.success("图片上传成功:" + file.getOriginalFilename());
        } catch (IOException e) {
            e.printStackTrace();
            // 捕获并处理IO异常,返回失败结果
            return Result.failed("图片上传失败:" + e.getMessage());
        }
    }

}

随后文件上传便可以加载到webapp/img中啦!在tomcat设置中on frame deactivation为Update Resource则不需要重新部署文件,便可以从外部通过路径访问新上传的图片。当然通过路径访问静态资源也需要设置相关配置:

java 复制代码
    //开启静态资源
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
相关推荐
Charles Ray17 分钟前
C++学习笔记 —— 内存分配 new
c++·笔记·学习
我要吐泡泡了哦1 小时前
GAMES104:15 游戏引擎的玩法系统基础-学习笔记
笔记·学习·游戏引擎
骑鱼过海的猫1231 小时前
【tomcat】tomcat学习笔记
笔记·学习·tomcat
贾saisai3 小时前
Xilinx系FPGA学习笔记(九)DDR3学习
笔记·学习·fpga开发
北岛寒沫3 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习
铁匠匠匠5 小时前
从零开始学数据结构系列之第六章《排序简介》
c语言·数据结构·经验分享·笔记·学习·开源·课程设计
架构文摘JGWZ6 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
小齿轮lsl6 小时前
PFC理论基础与Matlab仿真模型学习笔记(1)--PFC电路概述
笔记·学习·matlab
Aic山鱼7 小时前
【如何高效学习数据结构:构建编程的坚实基石】
数据结构·学习·算法
qq11561487077 小时前
Java学习第八天
学习