当前位置: 首页 > ops >正文

ElementUI之Upload 上传的使用

文章目录

  • 说明
  • SSM使用
    • 引入依赖
    • 在spring-mvc.xml中加入配置
    • 创建上传工具类AliOssUtil
    • 响应工具类ResultJSON
    • 编写controller
  • 自动上传
    • 代码编写
    • 结果如下演示
  • 手动上传
    • 前端代码编写
    • 后端代码编写
    • 结果演示如下

说明

为了方便演示,前后端代码一起写了
关于对象存储请看我另一篇博客
阿里云对象存储OSS的使用

SSM使用

引入依赖

<!--阿里云OSS依赖--><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version></dependency><dependency><groupId>javax.activation</groupId><artifactId>activation</artifactId><version>1.1.1</version></dependency><!-- no more than 2.3.3--><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.3</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency>

在spring-mvc.xml中加入配置

<!-- 配置 MultipartResolver 用于文件上传 --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!-- 设置最大上传文件大小 --><property name="maxUploadSize" value="10485760"/> <!-- 10MB --><property name="maxInMemorySize" value="4096"/><property name="defaultEncoding" value="UTF-8"/></bean>

创建上传工具类AliOssUtil

package com.Teenage_education_network.utils;import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;import java.io.InputStream;public class AliOssUtil {private static final String ENDPOINT = "https://oss-cn-beijing.aliyuncs.com";private static final String ACCESS_KEY_ID = "你的id";private static final String SECRET_ACCESS_KEY = "你的秘钥";private static final String BUCKET_NAME = "项目名";/** uploadFile方法* objectName:文件名称比如 "YEjdihp893bif1.jpg"* inputStream:文件流,用于读取文件比如,D:\Users\Administrator\Desktop\YEjdihp893bif1.jpg* *///上传文件,返回文件的公网访问地址public static String uploadFile(String objectName, InputStream inputStream){// 创建OSSClient实例。OSS ossClient = new OSSClientBuilder().build(ENDPOINT,ACCESS_KEY_ID,SECRET_ACCESS_KEY);//公文访问地址String url = "";try {// 创建存储空间。ossClient.createBucket(BUCKET_NAME);ossClient.putObject(BUCKET_NAME, objectName, inputStream);// 这里是返回阿里云的url地址url = "https://"+BUCKET_NAME+"."+ENDPOINT.substring(ENDPOINT.lastIndexOf("/")+1)+"/"+objectName;} catch (OSSException oe) {System.out.println("Caught an OSSException, which means your request made it to OSS, "+ "but was rejected with an error response for some reason.");System.out.println("Error Message:" + oe.getErrorMessage());System.out.println("Error Code:" + oe.getErrorCode());System.out.println("Request ID:" + oe.getRequestId());System.out.println("Host ID:" + oe.getHostId());} catch (ClientException ce) {System.out.println("Caught an ClientException, which means the client encountered "+ "a serious internal problem while trying to communicate with OSS, "+ "such as not being able to access the network.");System.out.println("Error Message:" + ce.getMessage());} finally {if (ossClient != null) {ossClient.shutdown();}}return url;}
}

响应工具类ResultJSON

package com.hsh.pojo.tdo;import java.io.Serializable;/*** @Author: wzy* @Date: 2024/11/13 11:03* @Description: 返回结果类*/
public class ResultJSON<T> implements Serializable {private Integer code;private String msg;private T data;public ResultJSON(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}/*** 操作成功或者失败* @param c 受影响行数* @return 当前传入的受影响行数>0则返回成功,否则返回失败*/public static  ResultJSON successORerror(int c){return c>0?new ResultJSON(200,"操作成功",c):new ResultJSON(400,"操作失败",c);}public static ResultJSON success(){return new ResultJSON(200,"操作成功",null);}public static ResultJSON success(String msg){return new ResultJSON(200,msg,null);}public static <T> ResultJSON success(T data){return new ResultJSON(200,"操作成功",data);}public static ResultJSON success(Integer code,String msg){return new ResultJSON(code,msg,null);}public static <T> ResultJSON success(String msg,T data){return new ResultJSON(200,msg,data);}public static <T> ResultJSON success(Integer code,String msg,T data){return new ResultJSON(code,msg,data);}public static ResultJSON error(){return new ResultJSON(500,"操作失败",null);}public static ResultJSON error(String msg){return new ResultJSON(500,msg,null);}public static ResultJSON error(Integer code,String msg){return new ResultJSON(code,msg,null);}public T getData() {return data;}public void setData(T data) {this.data = data;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}

编写controller

package com.hsh.controller;import com.hsh.pojo.tdo.ResultJSON;
import com.hsh.utils.AliOssUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.UUID;/*** @author xrkhy* @date 2025/9/6 19:05* @description*/@RestController
@RequestMapping("/upload")
public class UploadController {// 本次请求通过elementPlus的el-upload组件上传图片,通过el-upload组件的属性发起请求// 前端上传路径action="/api/upload/imgUpload" 要和后端一致 这里的/api是前端的反向代理的标识// 前端的name="img" 是这里的形参名// 前端的请求头添加token  :headers="{'Authorization':tokenStore.token}"@PostMapping("/imgUpload")public ResultJSON<String> imgUpload(@RequestParam("img") MultipartFile img) throws IOException {System.out.println(img);if (img == null || img.isEmpty()) {// 处理文件为空的情况return ResultJSON.error("文件不能为空");}String originalFilename = img.getOriginalFilename();// 生成新的唯一的文件名String fileNmae = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));String url = AliOssUtil.uploadFile(fileNmae, img.getInputStream());System.out.println(url);return ResultJSON.success("添加成功",url);}
}

自动上传

代码编写

<template><el-form:model="productForm"label-width="120px"label-position="right"><!-- 用户基础信息 --><el-form-item label="商品名称" prop="productName"><el-input v-model="productForm.productName"></el-input></el-form-item><el-form-item label="封面图片"><!-- :auto-upload 设置是否自动上传 true自动上传 --><!-- action为你的请求路径:你要替换为你的上传API地址 --><!-- name: 上传的文件字段名 (也就是后端的参数 我这里是img)后端的接收参数如下就是我上面写的UploadControllerpublic ResultJSON<String> imgUpload(@RequestParam("img") MultipartFile img){}--><!-- :on-success="handleAvatarSuccess" 上传成功回调 --><!-- :before-upload="beforeAvatarUpload"上传前校验 --><!--  list-type="picture-card" 文件列表的类型 这里不需要因为已经有<i class="el-icon-plus" v-if="!productForm.imageUrl"></i>代替了--><!-- :show-file-list="false" 是否显示已上传文件列表 --><!-- 除了上面还可以设置响应头,配置如下:headers="{'Authorization':tokenStore.token}"--><el-upload:auto-upload="true"action="http://localhost:8080/upload/imgUpload"name="img":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload":show-file-list="false"><!-- v-if="!productForm.imageUrl" 是如果上传成功这个+图标(<i class="el-icon-plus"></i>)上传的提示就不显示了  --><istyle="font-size: 20px; border: 1px solid #ccc; padding: 20px"class="el-icon-plus"v-if="!productForm.imageUrl"></i><img style="width: 100px" v-else :src="productForm.imageUrl" /></el-upload></el-form-item><el-form-item label="商品价格" prop="productPrice"><el-input-numberv-model="productForm.productPrice":precision="2":step="0.01"></el-input-number></el-form-item><el-form-item label="商品库存" prop="productStock"><el-input-numberv-model="productForm.productStock"label="描述文字"></el-input-number></el-form-item><!-- 操作按钮 --><el-form-item><el-button type="primary" @click="submitForm">提交</el-button><el-button @click="resetForm">重置</el-button></el-form-item></el-form>
</template><script>
export default {data() {return {productForm: {productId: null,productName: "",imageUrl: "",productPrice: "",productStock: ""},}}methods: {// 上传成功后的回调handleAvatarSuccess(res, file) {this.productForm.imageUrl = res.data;},// 上传前的校验beforeAvatarUpload(file) {const isJPG = file.type === "image/jpeg" || file.type === "image/png";const isLt2M = file.size / 1024 / 1024 < 2;if (!isJPG) {this.$message.error("上传头像图片只能是 JPG 或 PNG 格式!");}if (!isLt2M) {this.$message.error("上传头像图片大小不能超过 2MB!");}return isJPG && isLt2M;},submitForm() {console.log("提交的数据:", this.formData);// 这里在发起请求},}
}
</script>

结果如下演示

在这里插入图片描述
上面数据确实是拿到了,此时在点击提交发送。
在这里插入图片描述

手动上传

前端代码编写

<template><div><h1>图片手动提交</h1><el-form:model="productForm"style="width: 500px"label-width="120px"label-position="right"><!-- 用户基础信息 --><el-form-item label="商品名称" prop="productName"><el-input v-model="productForm.productName"></el-input></el-form-item><el-form-item label="封面图片"><!-- :auto-upload 设置是否自动上传 true自动上传 --><!-- action为你的请求路径:你要替换为你的上传API地址 --><!--  list-type="picture-card" 文件列表的类型 这里不需要因为已经有<i class="el-icon-plus" v-if="!productForm.imageUrl"></i>代替了--><!-- :show-file-list="false" 是否显示已上传文件列表 这里关闭 --><!-- v-if="!productForm.imageUrl" 是如果上传成功这个+图标(<i class="el-icon-plus"></i>)上传的提示就不显示了 --><el-upload:auto-upload="false"action="#":show-file-list="false":on-change="handleImgChange"><istyle="font-size: 20px; border: 1px solid #ccc; padding: 20px"class="el-icon-plus"v-if="!productForm.imageUrl"></i><img style="width: 100px" v-else :src="productForm.imageUrl" /></el-upload><!-- v-if="productForm.imageUrl" 如果图片不存在 img不显示 --><!-- <img v-if="imgURL" :src="imgURL" /> --></el-form-item><el-form-item label="商品价格" prop="productPrice"><el-input-numberv-model="productForm.productPrice":precision="2":step="0.01"></el-input-number></el-form-item><el-form-item label="商品库存" prop="productStock"><el-input-numberv-model="productForm.productStock"label="描述文字"></el-input-number></el-form-item><!-- 操作按钮 --><el-form-item><el-button type="primary" @click="submitForm">提交</el-button></el-form-item></el-form></div>
</template><script>
import axios from "axios";export default {name: "ImageUpload",data() {return {// 表单数据// 注意这里表单不能有字段为null,否则会报错// 比如productId: null, 发送给后端报错productForm: {productId: "",productName: "",imageUrl: "",productPrice: "",productStock: "",imgUrlFile: ""}};},methods: {// handleFileChange(file, fileList) {//   this.fileList = fileList;// },// 提交前实现封面图片预览handleImgChange(uploadFile) {// 预览图片// this.imgUrl = URL.createObjectURL(uploadFile.raw);this.productForm.imageUrl = URL.createObjectURL(uploadFile.raw);console.log(this.productForm.imageUrl);this.productForm.imgUrlFile = uploadFile.raw;// this.productForm.imageUrl = uploadFile.raw;},async submitForm() {const formData = new FormData();// 追加其他表单字段// 遍历 productForm 对象的属性for (const key in this.productForm) {// 将每个属性和值添加到 FormData 中formData.append(key, this.productForm[key]);}// 追加文件字段formData.append("file", this.imgUrlFile);this.clgFromData(formData);const res = await axios.post("http://localhost:8080/product/addProductWithImg",formData// 下面的headers可以不,会自动识别是json还是formdata// {//   headers: {//     "Content-Type": "multipart/form-data"//   }// });console.log(res);},clgFromData(formData) {for (let pair of formData.entries()) {console.log(pair[0] + ", " + pair[1]);}}}
};
</script><style scoped></style>

后端代码编写

package com.hsh.controller;import com.hsh.pojo.Product;
import com.hsh.pojo.tdo.ResultJSON;
import com.hsh.service.ProductService;
import com.hsh.utils.AliOssUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.List;
import java.util.UUID;@RestController
@RequestMapping("/product")
@CrossOrigin(origins = "http://localhost:8081")
public class ProductController {@AutowiredProductService productService;@PostMapping("/addProduct")public ResultJSON addProduct(@RequestBody Product product){System.out.println("product = " + product);return productService.addProduct(product);}// 注意 传入的product对象的属性不能是 null 也不能是 MultipartFile,否则报400的错误// 注意:java的product对象中,没有imgUrlFile属性。// 前端传入的product对象中,imgUrlFile属性是MultipartFile类型。@PostMapping("/addProductWithImg")public ResultJSON<Product> findProductById(@ModelAttribute Product product,@RequestParam(value = "imgUrlFile",required = false) MultipartFile imgUrlFile) throws IOException {System.out.println("product = " + product);System.out.println("imgFile = " + imgUrlFile);if (imgUrlFile == null || imgUrlFile.isEmpty()) {// 处理文件为空的情况return ResultJSON.error("文件不能为空");}String originalFilename = imgUrlFile.getOriginalFilename();// 生成新的唯一的文件名String fileNmae = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("."));String url = AliOssUtil.uploadFile(fileNmae, imgUrlFile.getInputStream());System.out.println(url);product.setImageUrl(url);return productService.addProduct(product);}}

结果演示如下

在这里插入图片描述

http://www.xdnf.cn/news/20162.html

相关文章:

  • C++语法之--多态
  • 了解Python
  • Ubuntu:Git SSH密钥配置的完整流程
  • 捷多邦揭秘超厚铜板:从制造工艺到设计关键环节​
  • 让字符串变成回文串的最少插入次数-二维dp
  • 单元测试详解
  • 基于树莓派与Jetson Nano集群的实验边缘设备上视觉语言模型(VLMs)的性能评估与实践探索
  • 【c++进阶系列】:万字详解AVL树(附源码实现)
  • ubuntu 系統使用過程中黑屏問題分析
  • 前端上传切片优化以及实现
  • 基于LLM开发Agent应用开发问题总结
  • equals 定义不一致导致list contains错误
  • SQL面试题及详细答案150道(81-100) --- 子查询篇
  • webrtc弱网-LossBasedBandwidthEstimation类源码分析与算法原理
  • 【Proteus仿真】定时器控制系列仿真——秒表计数/数码管显示时间
  • 【ComfyUI】混合 ControlNet 多模型组合控制生成
  • ANSYS HFSS边界条件的认识
  • 【LeetCode热题100道笔记】二叉树中的最大路径和
  • 9.FusionAccess桌面云
  • Spring的事件监听机制(一)
  • 03.缓存池
  • 【数学建模】质量消光系数在烟幕遮蔽效能建模中的核心作用
  • 故障诊断 | MATLAB基于CNN - LSSVM组合模型在故障诊断中的应用研究
  • 在Ubuntu上配置Nginx实现开机自启功能
  • 54.【.NET8 实战--孢子记账--从单体到微服务--转向微服务】--新增功能--实现手机邮箱注册
  • js面试题 什么是作用域?
  • 【Proteus仿真】定时器控制系列仿真——LED小灯闪烁/流水灯/LED灯带控制/LED小灯实现二进制
  • EG2104 SOP-8 带SD功能 内置600V功率MOS管 栅极驱动芯片
  • 智能客户服务支持智能体
  • 基于GOA与BP神经网络分类模型的特征选择方法研究(Python实现)