当前位置:网站首页>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>
边栏推荐
- Method keywords deprecated, externalprocname, final, forcegenerate
- 手把手教你学会js的原型与原型链,猴子都能看懂的教程
- Information System Project Manager - Chapter VIII project quality management
- LeetCode_ Gray code_ Medium_ 89. Gray code
- Learning and Exploration - function anti shake
- A5000 vGPU显示模式切换
- 精彩编码 【进制转换】
- PowerPivot——DAX(初识)
- Logstash expressway entrance
- leetcode先刷_Maximum Subarray
猜你喜欢
[玩转Linux] [Docker] MySQL安装和配置
Learning and Exploration - Seamless rotation map
Learn to explore - use pseudo elements to clear the high collapse caused by floating elements
The "white paper on the panorama of the digital economy" has been released with great emphasis on the digitalization of insurance
手把手教你学会js的原型与原型链,猴子都能看懂的教程
Speech recognition (ASR) paper selection: talcs: an open source Mandarin English code switching corps and a speech
[translation] micro survey of cloud native observation ability. Prometheus leads the trend, but there are still obstacles to understanding the health of the system
Introduction to enterprise lean management system
思維導圖+源代碼+筆記+項目,字節跳動+京東+360+網易面試題整理
Social recruitment interview experience, 2022 latest Android high-frequency selected interview questions sharing
随机推荐
(3) Web security | penetration testing | basic knowledge of network security construction, IIS website construction, EXE backdoor generation tool quasar, basic use of
PowerPivot——DAX(初识)
Leetcode 30. 串联所有单词的子串
Cesium 两点之间的直线距离
Cf960g - bandit Blues (type I Stirling number +ogf)
【翻译】供应链安全项目in-toto移至CNCF孵化器
MySQL information schema learning (I) -- general table
Standardized QCI characteristics
腾讯T2大牛亲自讲解,跳槽薪资翻倍
Method keywords deprecated, externalprocname, final, forcegenerate
腾讯安卓开发面试,android开发的基础知识
广州首个数据安全峰会将在白云区开幕
leetcode先刷_Maximum Subarray
Chic Lang: attributeerror: partially initialized module 'CV2' has no attribute 'GAPI_ wip_ gst_ GStreamerPipe
Example of shutter text component
腾讯字节阿里小米京东大厂Offer拿到手软,老师讲的真棒
数据的同步为每个站点创建触发器同步表
Mysql Information Schema 学习(二)--Innodb表
精彩编码 【进制转换】
腾讯T3手把手教你,真的太香了