热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:图片存储方案七牛云存储

本文由编程笔记#小编为大家整理,主要介绍了图片存储方案-七牛云存储相关的知识,希望对你有一定的参考价值。
本文由编程笔记#小编为大家整理,主要介绍了图片存储方案-七牛云存储相关的知识,希望对你有一定的参考价值。






简介


在我们实际的项目中,经常会将服务器进行划分,比如:专门运行我们程序的应用服务器、专门运行我们数据库的数据库服务器、还有负责文件存储的文件服务器、负责视频存储的服务器。


这些服务器组成我们的所有服务、各司其职,这样划分的目的相比大家也知道,减轻一台服务器服务器的压力。


当用户请求我们应用应用服务器的时候,由我们的应用再分别访问我们数据库服务器、文件存储服务器等,最后将请求的资源返回给我们的用户,这样构成整个应用的请求过程:



图片存储方案-七牛云存储

我们今天要讲的就是图片存储,图片储存的方案有很多,比如:可以使用Fastdfs或者HDFS、使用nginx搭建图片存储服务器。


现在比较流行的就是「云存储」,使用「阿里云、七牛云」等。这一节我们使用七牛云做了实例讲解。


七牛云入门


图片存储方案-七牛云存储注册完后直接登陆,登陆后右上角有一个「管理控制平台」,点击管理控制平台的产品首页,还要进行「实名认证才能创建对象存储存储空间」,实名认证后点击对象存储的「立即添加」:


图片存储方案-七牛云存储点击立即添加后来到对象存储空间的创建页面,点击「新建空间」图片存储方案-七牛云存储


创建存储空间后可以看见自己创建的空间的详细信息,并且可以创建多个存储空间,每一个存储空间相互独立,不会互相干扰。


七牛云提供了多种的方式操作对象存储服务,我们这里使用的是Java SDK方式,具体的使用可以在开发者中心查看:



图片存储方案-七牛云存储


图片存储方案-七牛云存储

Java SDK开发文档里面有详细的操作的API说明,以及要引入的依赖坐标。



图片存储方案-七牛云存储

代码实战


首先在自己的项目中引入七牛云的依赖坐标:



  com.qiniu
  qiniu-java-sdk
  7.2.0


从Java SDK的操作文档中,简单操作文档的上传的示例代码如下:


//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region0());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传,填写AK和SK以及buket name
String accessKey = "your access key";
String secretKey = "your secret key";
String bucket = "your bucket name";
//文件路径,如果是Windows情况下,格式是 D:\qiniu\test.png
String localFilePath = "/home/qiniu/test.png";
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
Auth auth = Auth.create(accessKey, secretKey);
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
    }
}

上面的是根据文件路径来上传文件,还支持字节数组上传到空间中:


//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region0());
//...其他参数参考类注释
UploadManager uploadManager = new UploadManager(cfg);
//...生成上传凭证,然后准备上传
String accessKey = "your access key";
String secretKey = "your secret key";
String bucket = "your bucket name";
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = null;
try {
    byte[] uploadBytes = "hello qiniu cloud".getBytes("utf-8");
    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);
        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
        }
    }
} catch (UnsupportedEncodingException ex) {
    //ignore
}

以及删除上传的文件:


//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.region0());
//...其他参数参考类注释
String accessKey = "your access key";
String secretKey = "your secret key";
String bucket = "your bucket name";
String key = "your file key";
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());
}

上面有提到比较关键的信息,因为使用七牛云服务要进行认证,上面有三个数据「AK、SK和bucket name」,AK和SK也就是AccessKey/SecretKey


AK和SK这个信息中可以在如下的页面获取,bucket name也就是你在创建存储空间的时候填信息的名称:




有了这些信息,我们可以将上面的代码封装成自己的工具类:


public class QiniuUtils {
    // 填写你的accessKey值
    public  static String accessKey = "your accessKey";
     // 填写你的secretKey 值
    public  static String secretKey = "your secretKey ";
    // 填写你的 bucket name值
    public  static String bucket = "your bucket name";
    /**
     * 上传文件
     * @param filePath 文件路径
     * @param fileName 文件名
     */
    public static void uploadFile(String filePath,String fileName){
        Configuration cfg = new Configuration(Zone.zone0());
        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
            }
        }
    }
    /**
     * 上传文件
     * @param bytes 文件字节数组
     * @param fileName 文件名
     */
    public static void uploadFile(byte[] bytes, String fileName){
        Configuration cfg = new Configuration(Zone.zone0());
        UploadManager uploadManager = new UploadManager(cfg);
        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);
        } catch (QiniuException ex) {
            Response r = ex.response;
            try {
                System.err.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
        }
    }
    /**
     * 删除文件
     * @param fileName 文件名
     */
    public static void deleteFile(String fileName){
        Configuration cfg = new Configuration(Zone.zone0());
        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());
        }
    }
}

然后写一个接口作为文件上传的测试类:


@Autowired 
private JedisPool jedisPool; //图片上传 
@RequestMapping("/uploadImage"
public ResponseResult upload(@RequestParam("imgFile")MultipartFile imgFile){ 
 try{
     //获取原始文件名 
  String originalFilename = imgFile.getOriginalFilename(); 
  //获取图片名后缀 
  int lastIndexOf = originalFilename.lastIndexOf("."); 
  String suffix = originalFilename.substring(lastIndexOf ‐ 1); 
  //使用UUID生成图片名,防止名称一样
  String fileName = UUID.randomUUID().toString() + suffix; QiniuUtils.uploadFile(imgFile.getBytes(),fileName); //图片上传成功 
  ResponseResult result = new ResponseResult (ResponseConstant.UPLOAD_SUCCESS,"上传成功"); 
  result.setData(fileName); 
  //将上传图片名称存入Redis,基于Redis的Set集合存储 
  jedisPool.getResource().sadd(ImageConstant.ALl_PIC_RESOURCES,fileName ); 
  return result; 
 }catch (Exception e){ 
  e.printStackTrace(); //图片上传失败 
  return new ResponseResult (ResponseConstant.UPLOAD_FAIL,"文件上传失败"); 
 } 
}

这里在作为图片上传的时候使用Redis的set集合进行缓存,这样做的目的就是,用户自己点击上传文件后,填写完信息,但是后面就有可能包填写的消息取消掉。


这样这些图片就会成为我们的垃圾图片,若是没有存储这些图片的信息,从此也找不到这些图片,这样这些垃圾图片就会占用空间。


我们的解决方案就是,先把所有的这些图片还存在Redis的一个Set集合中,叫做ALl_PIC_RESOURCES


然后把上传成功的图片还存在Redis的另一个Set集合中叫做L:SUCCESS_PIC_RESOURCES


最后系统起一个定时任务,定期清理掉ALl_PIC_RESOURCESL:SUCCESS_PIC_RESOURCES差值的图片数据,清理时间可以设置在晚上凌晨,这样对系统的性能影响就不会那么大。


定时任务可以选用Quartz,我相信这个定时任务框架应该很多人都用过,在项目中直接引入依赖坐标:



     org.quartz-scheduler
     quartz
 

 
     org.quartz-scheduler
     quartz-jobs
 


具体的定时任务的配置可以自行百度一下,这里只给出,定时任务清理图片的方法:


public void deleteImage(){
        //比较两个Set集合得到差集,得到无效的图片名称集合
        Set imageSet = redisTemplate.opsForSet().difference("ALl_PIC_RESOURCES""L:SUCCESS_PIC_RESOURCES");
        for (String imageName : imageSet ) {
            //删除图片
            QiniuUtils.deleteFileFrom(imageName );
            //删除缓存中无用的图片
            redisTemplate.boundSetOps("ALl_PIC_RESOURCES").remove(imageName );
        }
    }

好了,今天的实例讲解就到这里了,觉得有帮助的求个三连,我们下期再见。






推荐阅读
  • 校园表白墙微信小程序,校园小情书、告白墙、论坛,大学表白墙搭建教程
    小程序的名字必须和你微信注册的名称一模一样在后台注册好小程序。mp.wx-union.cn后台域名https。mp.wx-union.cn ... [详细]
  • 用ESP32与Python实现物联网(IoT)火焰检测报警系统
    下图是本案例除硬件连线外的3步导学开发过程,每个步骤中实现的功能请参考图中的说明。在硬件连线完成之后我们建议您先使用“一分钟上云体验”功能预先体验本案例的实际运行效果 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 20211101CleverTap参与度和分析工具功能平台学习/实践
    1.应用场景主要用于学习CleverTap的使用,该平台主要用于客户保留与参与平台.为客户提供价值.这里接触到的原因,是目前公司用到该平台的服务~2.学习操作 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • AFNetwork框架(零)使用NSURLSession进行网络请求
    本文介绍了AFNetwork框架中使用NSURLSession进行网络请求的方法,包括NSURLSession的配置、请求的创建和执行等步骤。同时还介绍了NSURLSessionDelegate和NSURLSessionConfiguration的相关内容。通过本文可以了解到AFNetwork框架中使用NSURLSession进行网络请求的基本流程和注意事项。 ... [详细]
  • mapreduce源码分析总结
    这篇文章总结的非常到位,故而转之一MapReduce概述MapReduce是一个用于大规模数据处理的分布式计算模型,它最初是由Google工程师设计并实现的ÿ ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 在tp5项目中引入ueditor编辑器并实例化后插入图片出现目录创建失败问题在查看网络上各种解决方案之后总结如下:根据官网提示主要是因为图片保存的路径无权限导致,官方文档链接:ht ... [详细]
author-avatar
牛牛的牛66_674
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有