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();
    }
相关推荐
Mephisto.java16 分钟前
【大数据学习 | kafka高级部分】kafka中的选举机制
大数据·学习·kafka
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
武子康2 小时前
大数据-212 数据挖掘 机器学习理论 - 无监督学习算法 KMeans 基本原理 簇内误差平方和
大数据·人工智能·学习·算法·机器学习·数据挖掘
使者大牙2 小时前
【大语言模型学习笔记】第一篇:LLM大规模语言模型介绍
笔记·学习·语言模型
As977_2 小时前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
ajsbxi2 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Rattenking2 小时前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
dsywws3 小时前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
道法自然04023 小时前
Ethernet 系列(8)-- 基础学习::ARP
网络·学习·智能路由器
爱吃生蚝的于勒3 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法