七牛云OSS的使用

图片上传

一、七牛云oss介绍

1.1 图片存储介绍

在实际开发中,我们会有很多处理不同功能的服务器。例如:

应用服务器:负责部署我们的应用

数据库服务器:运行我们的数据库

文件服务器:负责存储用户上传文件的服务器

image-20221220143849454

分服务器处理的目的是让服务器各司其职,从而提高我们项目的运行效率。

常见的图片存储方案:

方案一:使用nginx搭建图片服务器(最不常用)

方案二:使用开源的分布式文件存储系统,例如Fastdfs、HDFS等

方案三:使用云存储,例如阿里云、七牛云等

1.2 使用

1.2.1 注册账号
1.2.2 创建存储空间

1.2.3 开发文档

快速入门文档: https://developer.qiniu.com/kodo/1233/console-quickstart

java 开发SDK文档: https://developer.qiniu.com/kodo/1239/java

1.2.4 鉴权

鉴权:Java SDK的所有的功能,都需要合法的授权。授权凭证的签算需要七牛账号下的一对有效的Access KeySecret Key

1.2.5 工具类封装

1)添加依赖

<!--七牛云的图片上传依赖-->
<dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>7.16.0</version>
</dependency>

2)编写工具类

package com.woniuxy.portal.utils;import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;public class QiNiuUploadUtils {/*** 图片上传* @param uploadBytes* @param filename*/public static String uploadFile(byte[] uploadBytes, String filename){//构造一个带指定 Region 对象的配置类Configuration cfg = new Configuration(Region.region2());cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本//...其他参数参考类注释UploadManager uploadManager = new UploadManager(cfg);//...生成上传凭证,然后准备上传String accessKey = "2Zoe5PP-D0Jxf3pcIHjVzgOaVxxxx";String secretKey = "w4nWQuFo_0VpybJ6pnesFmOZ9xxxx";String bucket = "xxxx";//外链接域名String url = "http://smgw1dpx5.hn-bkt.xxxx";//默认不指定key的情况下,以文件内容的hash值作为文件名 文件的名称String key = filename;// 签名(密码)Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);try {Response response = uploadManager.put(uploadBytes, key, upToken);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);// http://smgw1dpx5.hn-bxxxx/zs.jpgreturn url +"/" +filename;} catch (QiniuException ex) {Response r = ex.response;System.err.println(r.toString());try {System.err.println(r.bodyString());} catch (QiniuException ex2) {//ignore}}return "";}/*** 删除文件* @param fileName*/public static void deleteFile(String fileName){//构造一个带指定 Region 对象的配置类Configuration cfg = new Configuration(Region.region2());//...其他参数参考类注释String accessKey = "2Zoe5PP-D0Jxf3pcIHjVzgOaVKAxxxx";String secretKey = "w4nWQuFo_0VpybJ6pnesFmOZ9xxxx";String bucket = "xxxx";//外链接域名Auth auth = Auth.create(accessKey, secretKey);BucketManager bucketManager = new BucketManager(auth, cfg);try {bucketManager.delete(bucket, fileName);} catch (QiniuException ex) {//如果遇到异常,说明删除失败System.err.println(ex.code());System.err.println(ex.response.toString());}}
}

二、头像上传

2.1 后端上传图片开发

2.2.1 编写上传图片的控制器
package com.woniuxy.portal.controller;import com.woniuxy.portal.utils.QiNiuUploadUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.UUID;@RestController
@RequestMapping("/upload")
@Api(tags = "文件上传")
public class UploadController{// @RequestPart 接受 前端 传递过来的图片 @ApiOperation("文件上传")@PostMapping("/images")public ResponseEntity<String> upload(@RequestPart MultipartFile file) throws IOException {// 1. 获取文件名称String originalFilename = file.getOriginalFilename();// 2. 重新设置文件的名称String uuid = UUID.randomUUID().toString();// 文件的名称 = uuid + 源文件的后缀String substring = originalFilename.substring(originalFilename.lastIndexOf("."));String fileName = uuid + substring;fileName = fileName.replaceAll("-", "");// 3. 调用图片上传的工具类String pathUrl = QiNiuUploadUtils.uploadFile(file.getBytes(), fileName);// 4. 响应数据return ResponseEntity.ok(pathUrl);}@ApiOperation("删除图片")@GetMapping("/delete")public ResponseEntity delete(String fileName){QiNiuUploadUtils.deleteFile(fileName);return ResponseEntity.ok().build();}
}
2.2.2 swagger测试

注意:springmvc处理上传的文件,要想通过swagger测试,需要添加注解@RequestPart,声明是一个文件上传表单

2.2.3 图片上传优化

存在的问题

String accessKey = "xxx";
String secretKey = "xxx";
String bucket = "xxx";

七牛云的账号全部是写在代码里面的,将来要修改的话不是非常方便,而且有可能会漏掉,所以,将配置项全部移到配置文件中

1)将账号配置到配置文件中

# 七牛云账号相关配置
qiNiu:accessKey: xxxsecretKey: xxxbucket: xxx

2)定义常量类

在common工程中定义一个常量类

package com.woniu.entity;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;/*** 常量类,定义各种常量*/
@Component
public class Constant {@Value("${qiNiu.accessKey}")private String accessKey;@Value("${qiNiu.secretKey}")private String secretKey;@Value("${qiNiu.bucket}")private String bucket;public static String ACCESSKEY;public static String SECRETKEY;public static String BUCKET;// 对象创建之后执行该方法@PostConstructpublic void init(){ACCESSKEY = this.accessKey;SECRETKEY = this.secretKey;BUCKET = this.bucket;}
}

3)修改工具类

String accessKey = Constant.ACCESSKEY;
String secretKey = Constant.SECRETKEY;
String bucket = Constant.BUCKET;

2.2 前端上传图片开发

2.2.1 从官网拷贝组件
<script setup>import { ref } from 'vue'import { ElMessage } from 'element-plus'const imgUrl = ref('')const handleAvatarSuccess = (response) => {console.log(response);// 文件上传成功后的处理,通常是返回头像的 URLimgUrl.value =response;}const submitAvatar = () => {//提交数据const user = {username:"zs",age:"30",url:imgUrl.value}if (imgUrl.value) {ElMessage.success('头像修改成功'+ user.url + ",用户信息进行修改")} else {ElMessage.error('请先上传头像')}}
</script><template><el-row class="avatar-uploader-container"><el-col :span="12" class="avatar-uploader-col"><el-uploadaction="http://localhost:8080/upload/images"class="avatar-uploader":show-file-list="false":on-success="handleAvatarSuccess"><img v-if="imgUrl" :src="imgUrl" class="avatar" /><img v-else src="@/assets/logo.png" class="default-avatar" /></el-upload><el-buttontype="success"size="large"@click="submitAvatar"class="upload-button">上传头像</el-button></el-col></el-row>
</template>
<style scoped>.avatar-uploader-container {display: flex;justify-content: center;align-items: center;margin-top: 30px;}.avatar-uploader-col {display: flex;flex-direction: column;justify-content: center;align-items: center;}.avatar-uploader {border: 2px solid #e4e7ed;border-radius: 50%;width: 120px;height: 120px;background-color: #f3f4f6;display: flex;justify-content: center;align-items: center;cursor: pointer;transition: border-color 0.3s ease;}.avatar-uploader:hover {border-color: #409eff;}.avatar {width: 100%;height: 100%;object-fit: cover;border-radius: 50%;}.default-avatar {width: 60%;height: 60%;object-fit: contain;}.upload-button {margin-top: 15px;background-color: #409eff;border-color: #409eff;color: white;border-radius: 20px;padding: 10px 30px;font-size: 16px;transition: background-color 0.3s ease, border-color 0.3s ease;}.upload-button:hover {background-color: #66b1ff;border-color: #66b1ff;}.upload-button:focus {outline: none;}.upload-button i {margin-right: 8px;}
</style>
2.2.3 修改上传成功的回调
//上传成功回调的处理方法 
const handleAvatarSuccess = (response) => {console.log(response);// 文件上传成功后的处理,通常是返回头像的 URLimgUrl.value =response;
}
2.2.3效果图:

image-20241105211250713

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/3669.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

重新构想定性数据分析:使用 NVivo 15 实现 AI、反思和备忘录

NVivo 是研究出版物中引用最多的定性数据分析软件 (QDA 软件),使用 NVivo v15 最新主要版本从定性和混合方法数据中发现更多信息&#xff0c;融合 Lumivero AI Assistant 更快地识别主题、运行高级查询和发现基于证据的见解&#xff0c;让您在更短的时间内获得严谨的研究结果。…

C++【string的模拟实现】

在前文我们讲解了string类接口使用&#xff08;C【string类的使用】(上),C【string类的使用】&#xff08;下&#xff09;&#xff09;&#xff0c;本片文章就来模拟实现string类。 注&#xff1a;本文实现的是string的部分重点内容&#xff0c;目的是为了更好的了解string&…

zabbix安装配置与使用

zabbix Zabbix的工作原理如下: 监控部分: Zabbix Agent安装在各个需要监控的主机上,它以主配置的时间间隔(默认60s)收集主机各项指标数据,如CPU占用率、内存使用情况等。 通讯部分: Agent会把收集的数据通过安全通道(默认10051端口)发送到Zabbix Server。Server会存储这些数…

7.3、实验三:RIPv2的基本配置

源文件&#xff1a; 7.3、实验三&#xff1a;RIPv2的基本配置: https://url02.ctfile.com/d/61945102-63684790-45f44b?p2707 (访问密码: 2707) 一、目的 能够使用RIPv2路由协议 二、实验要求 1.要求 使用RIPv2协议&#xff0c;使得PC0 和 Service0能够通信&#xff0c;…

石岩田心村的地面停车点(月卡350)

​我之前一直以为城中村里的地面停车场会比上屋地铁口的联天停车场便宜一些。没想到这个田心村月卡也是350元哈。比对面的园岭村还贵&#xff0c;元岭村月卡我记得才260元。 田心村停车场标识牌 序号 收费项目 收费标准 1 小车临时停放 10元/小时&#xff0c;超过1小时加收…

大模型学习笔记------CLIP模型的再思考

大模型学习笔记------CLIP模型的再思考 1、CLIP模型与Prompt(提示)的思考2、CLIP模型与ResNet等分类模型的根本区别3、结束语 上文已经讲 CLIP&#xff08;Contrastive Language-Image Pretraining&#xff09;这个模型&#xff0c;也讲了我的一些思考。但是&#xff0c;随着深…

Spring之依赖注入(DI)和控制反转(IoC)——配置文件、纯注解

依赖注入 依赖注入(Dependency Injection&#xff0c;简称 DI)与控制反转(loC)的含义相同&#xff0c;只不过这两 个称呼是从两个角度描述的同一个概念。对于一个 Spring 初学者来说&#xff0c;这两种称呼很难理解, 下面我们将通过简单的语言来描述这两个概念。 当Java对象&…

外网访问 Immich 照片管理软件

Immich 是一个自托管的照片和视频备份的平台&#xff0c;它允许用户在私有服务器上存储、管理和分享他们的照片&#xff0c;视频等媒体文件。 第一步&#xff0c;本地部署安装 Immich 1&#xff0c;检查 Docker 服务状态&#xff0c;确保 Docker 正常运行。 systemctl statu…

Linux网络命令:它用于实时监控网络接口的状态变化的命令 ip monitor详解

目录 一、概述 二、使用 1、语法 2、对象类型 3、常用选项 4、获取帮助 三、 示例 1. 监视链路层变化 2. 监视所有的网络变化 3. 仅监视路由表的变化 4. 监视特定网络接口的状态变化&#xff1a; 5. 监视网络接口地址的变化 四、实际应用 五、其他事项 一、概述 …

QT仿QQ聊天项目,第三节,实现主界面(好友列表)

目录 一&#xff0c;主界面示例 二&#xff0c;主界面控件组成 三&#xff0c;好友列表实现 1&#xff0c;好友列表的实现原理 2&#xff0c;实现示例代码 一&#xff0c;主界面示例 二&#xff0c;主界面控件组成 三&#xff0c;好友列表实现 1&#xff0c;好友列表的实现…

查找连表的倒数第k个节点

居安思危 何解&#xff1f; 1、假如有1、2、3三个节点&#xff0c;找倒数第二个&#xff0c;实际是整数第几个&#xff1f; 3-21 2 &#xff1a; 及 length - k 1 ,所以先遍历找节点长度&#xff0c;在遍历找所需节点 // 今天这不是力扣的var findNode function(head , k){…

练习LabVIEW第三十九题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十九题&#xff1a; 程序开始运行后要求用户输入密码&#xff0c;密码正确时字符串显示控件显示 “欢迎进入”&#x…

AI浪潮将席卷一切:本·霍洛维茨的AI战略与发展观点

近年来&#xff0c;人工智能&#xff08;AI&#xff09;的快速发展已经成为全球科技与经济变革的核心驱动力。从自驾汽车到生成式对话系统&#xff0c;AI正以前所未有的速度改变我们的生活、工作方式以及社会结构。然而&#xff0c;作为硅谷著名风险投资公司a16z的联合创始人&a…

windows下位机远程调试

一、前言 发布到下位机的程序在某种操作下出现异常&#xff0c;一种有效的远程调试手段能更快的帮助我们定位问题和解决问题。 VS结合Remote Debugger可以让下位机程序像运行在上位机上一样打断点调试&#xff0c;非常方便。 二、调试环境部署 1、设置下位机程序运行所在目录共…

C++ 多态原理

用一个题目引入&#xff1a; 现有代码&#xff1a; class Base { public:virtual void func(){cout << "Base:func()" << endl;} protected:int _a1;char _bx; }; void test1() {Base obj;cout << sizeof(obj) << endl; } 32位平台上输出的…

Javaweb梳理8——数据库设计

Javaweb梳理8——数据库设计 8 数据库设计8.1 数据库设计简介8.2 表关系(一对多)8.3 表关系&#xff08;多对多&#xff09;8.4 表关系&#xff08;一对一&#xff09; 8 数据库设计 8.1 数据库设计简介 软件的研发步骤 数据库设计概念 数据库设计就是根据业务系统的具体需…

TypeError: Cannot read properties of undefined (reading ‘__asyncLoader‘)

项目场景&#xff1a; vue3element-plus 项目场景&#xff1a;vue3element-plustsvite的技术栈开发的后台&#xff0c;一个后台列表页面&#xff0c;使用了ElTable组件 问题描述 页面提示报一个好像是异步的问题 runtime-core.esm-bundler.js:2261 Uncaught (in promise) Ty…

SAP ABAP开发学习——BADI增强操作步骤示例1

SAP ABAP开发学习——第三代增强&#xff08;BADI)-CSDN博客 SAP ABAP开发学习——BADI增强操作步骤示例2-CSDN博客 创建物料MM01的增强 首先进入SE24 打断点&#xff0c;运行事务MM01,启动debug,获得增强的名字 F8依次获得下一个增强的名字 继续获得增强 进入选择视图以及销…

odrive代码阅读笔记

电机参数 电流环带宽 atan2 // based on https://math.stackexchange.com/a/1105038/81278 float fast_atan2(float y, float x) {// a : min (|x|, |y|) / max (|x|, |y|)float abs_y fabsf(y);float abs_x fabsf(x);// inject FLT_MIN in denominator to avoid division …

C++多线程常见的数据竞争模式及示例分析

一、简单竞争 最简单的数据竞争是最常见的一种&#xff1a;两个线程在没有任何同步的情况下访问一个内置类型的变量。很多时候&#xff0c;这种竞争是良性的&#xff08;代码统计一些允许不精确的统计信息&#xff09;。 int var;void Thread1() { // 在一个线程中运行。var;…