从前端到后端全面解析文件上传
从前端到后端全面解析文件上传
- 1.前端准备(vue+element-ui)
- 2.后端准备(SpringBoot+minio+mysql)
- 2.1解决跨域
- 2.2配置minio与mysql
- 2.3controller层
- 2.4service层
1.前端准备(vue+element-ui)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>index</title><link rel="stylesheet" href="./element-ui/lib/theme-chalk/index.css"><link rel="stylesheet" href="css/index.css"><script src="js/vue.js"></script><script src="js/axios-0.18.0.js"></script><script src="./element-ui/lib/index.js"></script><style>.avatar-uploader .el-upload {border: 1px dashed #d9d9d9;border-radius: 6px;cursor: pointer;position: relative;overflow: hidden;}.avatar-uploader .el-upload:hover {border-color: #409EFF;}.avatar-uploader-icon {font-size: 28px;color: #8c939d;width: 178px;height: 178px;line-height: 178px;text-align: center;}.avatar {width: 178px;height: 178px;display: block;}</style>
</head>
<style>
</style>
<body><div id="app"><el-uploadclass="avatar-uploader"action="http://localhost:8088/members/upload":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><img v-if="imageUrl" :src="imageUrl" class="avatar"><i v-else class="el-icon-plus avatar-uploader-icon"></i><p>{{name}}</p></el-upload>
</div><script>new Vue({el: "#app",data() {return {imageUrl: '',name:'',url:'',};},methods: {handleAvatarSuccess(res, file) {this.imageUrl = URL.createObjectURL(file.raw);this.name=file.response.namethis.url=file.response.urlconsole.log(file)},beforeAvatarUpload(file) {const isLt2M = file.size / 1024 / 1024 < 10;if (!isLt2M) {this.$message.error('上传头像图片大小不能超过 10MB!');}return isLt2M;}}})
</script>
</body>
</html>
2.后端准备(SpringBoot+minio+mysql)
2.1解决跨域
package com.data211.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;/*** @author rjj* @date 2023/2/3 - 15:15*/
@Configuration
public class GlobalCorsConfig {/*** 允许跨域调用的过滤器*/@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();//允许白名单域名进行跨域调用(设置http://localhost:8080/ 表示指定请求源允许跨域)config.addAllowedOriginPattern("*");//允许跨越发送cookieconfig.setAllowCredentials(true);//放行全部原始头信息config.addAllowedHeader("*");//允许所有请求方法跨域调用config.addAllowedMethod("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();//指定拦截路径source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}
}
2.2配置minio与mysql
pom依赖
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.5.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><!--第三方工具jar包--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.17</version></dependency>
配置文件配置
server:port: 8088spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: username: rootpassword: mybatis-plus:mapper-locations: classpath:mapper/*.xml
# 配置别名type-aliases-package: com.data211.pojoglobal-config:db-config:
# 主键自增长id-type: auto
# 表名前缀table-prefix: data211_
# 逻辑删除logic-delete-value: 1logic-not-delete-value: 0
# 控制台输出操作数据库日志configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplminio:endpoint: accessKey: secretKey: bucket:files:
配置minio客户端
package com.data211.config;import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/**@author rjj@date 2023/2/18 - 17:37
*/
@Configuration
public class MinioConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Beanpublic MinioClient minioClient() {MinioClient minioClient =MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();return minioClient;}
}
2.3controller层
@RequestMapping(value = "/upload")public UploadFileResultDto upload(@RequestPart("file") MultipartFile file) throws IOException {return membersService.upload(file);};
2.4service层
package com.data211.service.impl;import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.data211.dao.MembersDao;
import com.data211.dto.UploadFileResultDto;
import com.data211.pojo.MediaFiles;
import com.data211.pojo.Members;
import com.data211.service.IMembersService;
import com.data211.utils.BaseContext;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;@Service
public class MembersServiceImpl extends ServiceImpl<MembersDao, Members> implements IMembersService {@Resourceprivate MinioClient minioClient;//普通文件桶@Value("${minio.bucket.files}")private String bucket_Files;@Resourceprivate MembersServiceImpl membersService;@Resourceprivate MediaFilesServiceImpl mediaFilesService;@Overridepublic UploadFileResultDto upload(MultipartFile file) throws IOException {String fileMd5 = DigestUtil.md5Hex(file.getBytes());String folder = getFileFolder(new Date(), true, true, true);String filename = fileMd5+file.getName().substring(file.getName().lastIndexOf("."));MediaFiles mediaFiles = null;try {//TODO 上传到minioaddMediaFilesToMinIO(file, bucket_Files, folder+filename);//TODO 上传到数据库 (用Spring控制的代理对象实现事务控制生效)mediaFiles = membersService.addMediaFilesToDb(BaseContext.getUserId(),filename,folder+filename);UploadFileResultDto uploadFileParamsDto = new UploadFileResultDto();BeanUtils.copyProperties(mediaFiles,uploadFileParamsDto);return uploadFileParamsDto;} catch (Exception e) {e.printStackTrace();}return null;}@Override@Transactionalpublic MediaFiles addMediaFilesToDb(String userId, String filename,String url) {MediaFiles mediaFiles = new MediaFiles(userId, filename, url);mediaFilesService.save(mediaFiles);return mediaFiles;}public void addMediaFilesToMinIO(MultipartFile file, String bucket, String objectName) throws IOException {// 将文件字节输入到内存流中ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(file.getBytes());//获取文件类型String contentType = file.getContentType();try {PutObjectArgs putObjectArgs =PutObjectArgs.builder().bucket(bucket).object(objectName)//-1 表示文件分片按 5M(不小于 5M,不大于 5T),分片数量最大10000.stream(byteArrayInputStream, byteArrayInputStream.available(), -1).contentType(contentType).build();minioClient.putObject(putObjectArgs);} catch (Exception e) {e.printStackTrace();}}private String getFileFolder(Date date, boolean year, boolean month, boolean day) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//获取当前日期字符串String dateString = sdf.format(new Date());//取出年、月、日String[] dateStringArray = dateString.split("-");StringBuffer folderString = new StringBuffer();if (year) {folderString.append(dateStringArray[0]);folderString.append("/");}if (month) {folderString.append(dateStringArray[1]);folderString.append("/");}if (day) {folderString.append(dateStringArray[2]);folderString.append("/");}return folderString.toString();}}
相关文章:
从前端到后端全面解析文件上传
从前端到后端全面解析文件上传1.前端准备(vueelement-ui)2.后端准备(SpringBootminiomysql)2.1解决跨域2.2配置minio与mysql2.3controller层2.4service层1.前端准备(vueelement-ui) <!DOCTYPE html> <html lang"en"> <head><meta charset"…...
全网火爆,软件测试面试题大全,接口测试题+回答 (18k+的offer)
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 面试测试工程师的时…...
【iOS】—— 浅看block源码
block 文章目录block如何通过终端clang生成源码cpp文件block实质截获自动变量全局变量和静态变量的截获__block说明符iOS开发“强弱共舞”——weak和strong配套使用解决block循环引用问题如何通过终端clang生成源码cpp文件 之前在学习block中学习的比较浅,只看了oc…...
I.MX6ULL_Linux_系统篇(23) busybox文件系统构建
Linux“三巨头”已经完成了 2 个了,就剩最后一个 rootfs(根文件系统)了,本章我们就来学习一下根文件系统的组成以及如何构建根文件系统。这是 Linux 移植的最后一步,根文件系统构建好以后就意味着我们已经拥有了一个完整的、可以运行的最小系…...
shpjs将.zip文件转成geoJson
一、npm install shpjs二、import shp from shpjs三、async setLayerSource() {const geoJsonData await shp(dataUrl)}一直报错:是因为Buffer这个插件一直没找到Uncaught Error: nodebuffer is not supported by this browser解决办法npm install node-polyfill-w…...
eBay是不是一定要养号?是的
相信每个运营过eBay的用户遇到过这个棘手的问题,eBay个人账户的刊登数量是有限的,尤其是新账户只有5个sku,所以一开始的运营会比较艰难。想要快点走上正轨的话,就一定要去注重这个“养号”。eBay运营模式 1.拍卖 eBay最开始是一个…...
宝塔(二):升级JDK版本
目录 背景 一、下载JDK17 二、配置环境变量 三、配置新的JDK路径 背景 宝塔的软件商店只有JDK8,不满足我当前项目所需的JDK版本,因此想对JDK版本进行升级,升级为JDK17。 一、下载JDK17 先进入 /usr/lib/jvm 目录 点击终端,进…...
【LeetCode】螺旋矩阵 [M](数组)
54. 螺旋矩阵 - 力扣(LeetCode) 一、题目 给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,…...
实验二:动态规划
1.双11的红包雨 问题描述 双11到了,据说这2天会下红包雨,每个红包有不同的价值,小k好开心,但有个规则,就只能接掉落在他身旁的10米范围内的红包(0-10这11个位置)。小k想尽可能的多抢红包&…...
华为机试 HJ27 查找兄弟单词
题目链接:https://www.nowcoder.com/practice/03ba8aeeef73400ca7a37a5f3370fe68?tpId37&tqId21250&rp1&ru/exam/oj/ta&qru/exam/oj/ta&sourceUrl%2Fexam%2Foj%2Fta%3Fdifficulty%3D3%26page%3D1%26pageSize%3D50%26search%3D%26tpId%3D37%26t…...
佩戴舒适的蓝牙耳机有哪些?佩戴舒适的蓝牙耳机推荐
音乐对许多人而言,都是一种抚慰生命的力量,特别是在上下班的时候,在熙熙攘攘的人流中,戴着耳机听一首动听的曲子,无疑会让人心情变得更加舒畅,要想获得出色的音乐体验,没有一副出色的耳机可不行…...
ESXI主机安装Zabbix 6.2
1:首先下载Zabbix Appliance 2:还需要下载VMware converter ,这个需要VMware的账号,或者从其他地方下载也可以。 3:vmdk格式的 image 可直接在 VMware Player、 Server 和 Workstation 产品中使用。要在 ESX,、ESXi 和 vSphere 中…...
【Linux 网络编程1】使用UDP/TCP编写套接字,多进程/多线程版本的TCP编写的套接字,将套接字封装
目录 1.学习网络编程前的一些基础知识 2.UDP(user datagram protocol)协议的特点 3.使用有UPD编写套接字 4.使用TCP编写套接字 4.2.TCP客服端 4.3.TCP服务器端 4.4.单进程版本(没有人会使用) 4.5.多进程版本 4.6.多线程版本 5.把套接字封装 1…...
滑动窗口求最大和最小
滑动窗口 要区分最小和最大滑窗,内层while循环的条件和更新结果的地方 核心: 关键的区别在于,最大滑窗是在迭代右移右边界的过程中更新结果,而最小滑窗是在迭代右移左边界的过程中更新结果。 最小滑窗 给定数组 nums࿰…...
跟ChatGPT学量化,菜鸟炒股也不怕
你是一个python资深量化开发工程师,请介绍量化交易的基本框架 量化交易的基本框架包括以下几个步骤: 数据获取:获取市场数据和公司财务数据等,可以使用API接口、爬虫等方式获取。数据清洗和预处理:对获取到的数据进行清…...
扬帆优配|2600亿新能源巨头狂飙!外资唱多中国:再涨15%
全国停摆的危机,正在迫临法国。 大停工正在将法国推向风险境地。法国政府估计,当地时间3月7日,将迸发全国大型停工游行。法国总工会宣告,到时将让全法国停摆。法国担任交通业务的部长级代表克莱蒙博讷正告称,7日将成为…...
ChatGPT技术与商业模式及产业发展布局方案
文章目录模块一:概念模块二:架构模块三:技术模块四:算力模块五:体验模块六:应用模块七:商业模块八:产业模块九:建议结语主要内容: 采用模块化教学方法&#x…...
CIMCAI port ai shipping ai artificial intelligence smart port
上海人工智能独角兽中集集团高科技中集飞瞳,是全球应用落地最广,规模最大,最先进的的港航人工智能高科技企业,工业级成熟港航人工智能产品全球规模化落地应用,全球前三大船公司及港口码头应用落地。上海人工智能独角兽…...
《数据解构》HashMap源码解读
👑作者主页:Java冰激凌 📖专栏链接:数据结构 目录 了解HashMap HashMap的构造 两个参数的构造方法 一个参数的构造方法 不带参数的构造方法 哈希表初始化的长度 HashMap源码中的成员 Pt Get 了解HashMap 首先我们要明…...
Databend 开源周报 第 83 期
Databend 是一款现代云数仓。专为弹性和高效设计,为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务:https://app.databend.com 。Whats New探索 Databend 本周新进展,遇到更贴近你心意的 Databend 。Support for WebHDFSHDFS 是大数…...
Spring | 基础
1. IOC和DI IOC:控制反转,其思想是反转资源获取的方向,传统的资源查找方式要求组件向容器发起请求查找资源,作为回应,容器适时的返回资源。而应用了 IOC 之后,则是**容器主动地将资源推送给它所管理的组件…...
windows7安装sql server 2000安装步骤 及安装过程中遇到的问题和解决方式
提示:文章写完后windows7安装sql server 2000安装步骤 及安装过程中遇到的问题和解决方式, 文章目录一、ms sql server 2000是什么?版本简介:**特点:****优点:**二、步骤1.下载安装包及Sq4补丁包2.安装 ms …...
Python 开发-批量 FofaSRC 提取POC 验证
数据来源 学习内容和目的: ---Request 爬虫技术,lxml 数据提取,异常护理,Fofa 等使用说明---掌握利用公开或 0day 漏洞进行批量化的收集及验证脚本开发Python 开发-某漏洞 POC 验证批量脚本---glassfish存在任意文件读取在默认4…...
Linux系统中部署软件
目录 1.Mysql 2.Redis 3.ZooKeeper 声明 致谢 1.Mysql 参考:CentOS7安装MySQL 补充: ① 执行:rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 再执行:yum -y install mysql-community-server ② mysql…...
PHP常用框架介绍与比较
HP是一种广泛应用于Web开发的编程语言。随着互联网的快速发展,PHP的应用场景变得越来越广泛,从简单的网站到复杂的Web应用程序都可以使用PHP来开发。为了更好地组织和管理PHP代码,开发人员经常会使用框架来提高开发效率和代码质量。 本文将介绍一些常用的PHP框架,并进行简…...
Umi + React + Ant Design Pro 项目实践(一)—— 项目搭建
学习一下 Umi、 Ant Design 和 Ant Design Pro 从 0 开始创建一个简单应用。 首先,新建项目目录: 在项目目录 D:\react\demo 中,安装 Umi 脚手架: yarn create umi # npm create umi安装成功: 接下来,…...
MySQL知识点总结(1)
目录 1、sql、DB、DBMS分别是什么,他们之间的关系? 2、什么是表? 3、SQL语句怎么分类呢? 4、导入数据 5、什么是sql脚本呢? 6、删除数据库 7、查看表结构 8、表中的数据 10、查看创建表的语句 11、简单的查询…...
day45第九章动态规划(二刷)
今日任务 70.爬楼梯(进阶)322.零钱兑换279.完全平方数 70.爬楼梯(进阶) 题目链接: https://leetcode.cn/problems/climbing-stairs/description/ 题目描述: 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不…...
第十四届蓝桥杯第三期模拟赛原题与详解
文章目录 一、填空题 1、1 找最小全字母十六进制数 1、1、1 题目描述 1、1、2 题解关键思路与解答 1、2 给列命名 1、2、1 题目描述 1、2、2 题解关键思路与解答 1、3 日期相等 1、3、1 题目描述 1、3、2 题解关键思路与解答 1、4 乘积方案数 1、4、1 题目描…...
client打包升级
目录 前言 一、client如何打包升级? 二、使用步骤 1.先进行改版本 2.执行打包升级命令 总结 前言 本文章主要记录一下,日常开发中,常需要进行打包升级的步骤。 一、client如何打包升级? # 升级发布版本 ## 修改版本 * 父p…...
能解析国外网站的dns/引流推广的句子
要排除客户端与服务器端的连接问题,首先检查客户端配置是否正确(客户端配置必须与数据库服务器端监听配置一致), 再根据错误提示解决。下面列出几种常见的连接问题 1、 ORA----12541: TNS: 没有监听器 显而易见,服务器端的监听器没有启动&…...
做网站的手机软件/今日新闻最新头条10条摘抄
结直肠癌是常见的消化道肿瘤之一,我国的结直肠癌发病率和病死率均居于前列。近年来随着靶向治疗和免疫治疗在结直肠癌治疗中的应用,晚期结直肠癌的治疗进入了一个新的阶段。结直肠癌疗效预测和预后评估分子标志物对临床制订正确的治疗方案非常重要。在7月…...
网站设计合同/百度双十一活动
我是linux 的服务器,navicat12的客户端, 开始链接的时候需要开服务器上得对外爆漏端口 3306,方法: 添加指定需要开放的端口: firewall-cmd --add-port123/tcp --permanent 重载入添加的端口: firewall-cmd …...
wordpress织梦 更快/奶茶网络营销策划方案
新买的电脑,用一段时间后,可能会出现各种各样的问题,如果垃圾过多、启动速度慢可以通过软件对电脑进行优化,但是如果电脑中毒,反复重启,排除是硬件问题的话,最好的解决之道就是重新安装系统了&a…...
深圳网站建设培训班/seo推广系统
论理靠约架,打架靠群殴,无论说得如何冠冕堂皇,如何煽情,说白了,都是没有开化的野蛮人! 这些人谈民主,是当下最大的冷笑话。 那一大块还是一大坨的东西,别以为黄色就能冒充金子&#…...
怎样做公司的网站首页/关键词优化 搜索引擎
题意: 有t组测试数据,每组测试数据给一个矩阵n,m。 接下来给出n行,每行第一个数字为该行的编号(从1开始),然后给出这行不能走的y坐标。 问从出发点(1,1)&…...