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();
    }
相关推荐
西岸行者10 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意10 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码10 天前
嵌入式学习路线
学习
毛小茛10 天前
计算机系统概论——校验码
学习
babe小鑫10 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms10 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下10 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。10 天前
2026.2.25监控学习
学习
im_AMBER10 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J10 天前
从“Hello World“ 开始 C++
c语言·c++·学习