当前位置:网站首页>22-07-05 七牛云存储图片、用户头像上传
22-07-05 七牛云存储图片、用户头像上传
2022-07-06 12:07:00 【£小羽毛】
上传的文件保存到哪里好
方式1.当前项目所在的服务器。但是不太好,有很多的问题
问题一:会占用tomcat的硬盘空间,影响tomcat的运行效率;
问题二:用户上传的文件容易丢失(clean,会把target删除)
问题三:在集群环境下会产生数据的不一致。(上传头像上传的只是某一台服务器)
方式2.上传到专门的文件存储服务器,tomcat就是应用服务器,来部署应用的
2.1FASTDFS、HDFS 要自己搭建
2.2 购买第三方云存储:
阿里云、百度云、腾讯云、七牛云(视觉方面做的极致,视频、图片)
使用七牛云提供的对象存储服务来存储图片
注册并登录成功以后:
第一步:创建对象存储空间
在资源管理里点击新建存储空间
此时弹出页面:填好信息
可以创建多个存储空间,各个存储空间是相互独立的
第二步:查看存储空间信息
存储空间创建后,会在左侧的存储空间列表菜单中展示创建的存储空间名称,点击存储空间名称可以查看当前存储空间的相关信息
切换tab页到-文件管理
七牛云开发者中心
可以通过七牛云提供的开发者中心学习如何操作七牛云服务,地址:七牛开发者中心
对象存储 - 七牛开发者中心 点击对象存储,跳转到对象存储开发页面
写一个入门案例:
第一步:导入jar包:
<!--七牛云服务平台,第三方服务(图片上传)-->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
第二步:鉴权
我们的AK和SK在哪呢?
一会在Java代码里会用到这一对AK、SK的,到时候来这里复制就好了
文件上传:
在官网里是有案例的,我这里就是仿照那里写的测试代码
public void testUpload(){
//构造一个带指定 Zone 对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
//创建一个文件上传的管理器对象
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传
//你自己的AccessKey
String accessKey = "5awGQ0oY-NJUOECgxTnOQOHOG66W8wCvBJChUqmM";
//你自己的SecretKey
String secretKey = "pz_xQZbTrhFErQcGaeCLn-tkq_1F5uXQDCBo_2tc";
//你自己的空间的名字
String bucket = "shfxa0328-xym";
//如果是Windows情况下,格式是 D:\\qiniu\\test.png
String localFilePath = "D:/qiniu/test.jpg";
///key表示文件上传到七牛云中的名字,默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
//鉴权
Auth auth = Auth.create(accessKey, secretKey);
//创建一个文件上传标示token
String upToken = auth.uploadToken(bucket);
try {
//文件上传
Response response = uploadManager.put(localFilePath, key, upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
}
运行之前先施法,配置一下这里
运行,控制台打印如下
在七牛云上可以看到我们上传图片成功了,且文件名和我们控制台打印的结果是一样的
点击右边的文件详情,就可以看到这个文件的据图信息了
文件的删除
public void testDelete(){
//构造一个带指定 Zone 对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
//你自己的AccessKey
String accessKey = "5awGQ0oY-NJUOECgxTnOQOHOG66W8wCvBJChUqmM";
//你自己的SecretKey
String secretKey = "pz_xQZbTrhFErQcGaeCLn-tkq_1F5uXQDCBo_2tc";
//你自己的空间的名字
String bucket = "shfxa0328-xym";
//要删除的那个文件的名称
String key = "FnATf109bsayb0tYiZKgoHn96lQT";
Auth auth = Auth.create(accessKey, secretKey);
BucketManager bucketManager = new BucketManager(auth, cfg);
try {
bucketManager.delete(bucket, key);
} catch (QiniuException ex) {
//如果遇到异常,说明删除失败
System.err.println(ex.code());
System.err.println(ex.response.toString());
}
}
检查七牛云,文件确实被删除了
封装工具类QiniuUtils
这个工具类有3处是需要修改的
public class QiniuUtils {
private static String accessKey = "5awGQ0oY-NJUOECgxTnOQOHOG66W8wCvBJChUqmM";
private static String secretKey = "pz_xQZbTrhFErQcGaeCLn-tkq_1F5uXQDCBo_2tc";
private static String bucket = "shfxa0328-xym";
public static void upload2Qiniu(String filePath,String fileName){
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
UploadManager uploadManager = new UploadManager(cfg);
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(filePath, fileName, upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
} catch (QiniuException ex) {
Response r = ex.response;
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
}
//上传文件
public static void upload2Qiniu(byte[] bytes, String fileName){
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = fileName;
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
try {
Response response = uploadManager.put(bytes, key, upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
}
//删除文件
public static void deleteFileFromQiniu(String fileName){
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone2());
String key = fileName;
Auth auth = Auth.create(accessKey, secretKey);
BucketManager bucketManager = new BucketManager(auth, cfg);
try {
bucketManager.delete(bucket, key);
} catch (QiniuException ex) {
//如果遇到异常,说明删除失败
System.err.println(ex.code());
System.err.println(ex.response.toString());
}
}
public static String getUrl(String uuidName) {
return "http://rejg8ksr8.hn-bkt.clouddn.com/" + uuidName;
}
}
我们实现一个上传头像的功能
前端页面:
<form id="ec" th:action="@{/admin/upload/{id}(id=${id})}" method="post" enctype="multipart/form-data" class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label">上传头像:</label>
<div class="col-sm-10">
<input type="file" name="file" id="file" class="form-control" readonly/>
</div>
</div>
<div class="hr-line-dashed"></div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-2 text-right">
<button class="btn btn-primary" type="submit">确定</button>
<button class="btn btn-white" type="button" onclick="opt.closeWin();" value="取消">取消</button>
</div>
</div>
在页面上效果如下
选择完头像点击确定就会执行这样一段代码:
@PostMapping("/upload/{id}")
public String upload(@PathVariable("id") Long id, @RequestParam("file") MultipartFile multipartFile, Model model) throws IOException {
//id是用户的id
//1. 将图片上传到七牛云
//生成一个唯一的文件名
String originalFilename = multipartFile.getOriginalFilename();
String uuidName = FileUtil.getUUIDName(originalFilename);
QiniuUtils.upload2Qiniu(multipartFile.getBytes(),uuidName);
//2. 将图片信息保存到数据库
//2.1 获取图片的url
String headUrl = QiniuUtils.getUrl(uuidName);
//2.2 封装信息到Admin
Admin admin = new Admin();
admin.setId(id);
admin.setHeadUrl(headUrl);
//2.3 更新admin
adminService.update(admin);
//3. 显示成功页面
return successPage(model,"上传头像成功");
}
在数据库的acl_admin表中head_url字段确实变更了
去七牛云里,也是可以看到我们上传成功的头像的
要注意的点:一定要在spring-mvc的配置文件中开启文件上传解析器
<!--文件解析器-->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设定文件上传的最大值为100MB,100*1024*1024 -->
<property name="maxUploadSize" value="104857600" />
<!-- 设定文件上传时写入内存的最大值,如果小于这个参数不会生成临时文件,默认为10240 -->
<property name="maxInMemorySize" value="4096" />
<!-- 设定默认编码 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
边栏推荐
- Mysql Information Schema 學習(一)--通用錶
- Learn to explore - use pseudo elements to clear the high collapse caused by floating elements
- MySQL information Schema Learning (i) - - General table
- Wonderful coding [hexadecimal conversion]
- 【翻译】供应链安全项目in-toto移至CNCF孵化器
- Tensorflow2.0 self defined training method to solve function coefficients
- 某东短信登录复活 安装部署教程
- How to customize animation avatars? These six free online cartoon avatar generators are exciting at a glance!
- Interview assault 63: how to remove duplication in MySQL?
- Appx代码签名指南
猜你喜欢
Vscode debug run fluent message: there is no extension for debugging yaml. Should we find yaml extensions in the market?
Zero foundation entry polardb-x: build a highly available system and link the big data screen
【翻译】云原生观察能力微调查。普罗米修斯引领潮流,但要了解系统的健康状况仍有障碍...
(3) Web security | penetration testing | basic knowledge of network security construction, IIS website construction, EXE backdoor generation tool quasar, basic use of
Phoenix Architecture 3 - transaction processing
深度剖析原理,看完这一篇就够了
In simple terms, interview surprise Edition
Pay attention to the partners on the recruitment website of fishing! The monitoring system may have set you as "high risk of leaving"
理解 YOLOV1 第二篇 预测阶段 非极大值抑制(NMS)
[玩转Linux] [Docker] MySQL安装和配置
随机推荐
Tencent Android interview must ask, 10 years of Android development experience
广州首个数据安全峰会将在白云区开幕
CF960G - Bandit Blues(第一类斯特林数+OGF)
腾讯字节等大厂面试真题汇总,网易架构师深入讲解Android开发
OceanBase社区版之OBD方式部署方式单机安装
MySQL information schema learning (II) -- InnoDB table
腾讯安卓开发面试,android开发的基础知识
[translation] supply chain security project in toto moved to CNCF incubator
Database specific interpretation of paradigm
【翻译】供应链安全项目in-toto移至CNCF孵化器
HDU 1026 search pruning problem within the labyrinth of Ignatius and the prince I
MySql必知必会学习
POJ3617 Best Cow Line 馋
Learning and Exploration - Seamless rotation map
[translation] micro survey of cloud native observation ability. Prometheus leads the trend, but there are still obstacles to understanding the health of the system
LeetCode_格雷编码_中等_89.格雷编码
Web开发小妙招:巧用ThreadLocal规避层层传值
Carte de réflexion + code source + notes + projet, saut d'octets + jd + 360 + tri des questions d'entrevue Netease
LeetCode_ Double pointer_ Medium_ 61. rotating linked list
蓝桥杯 微生物增殖 C语言