当前位置: 代码网 > it编程>编程语言>Java > 基于SpringBoot + 七牛云 + Quartz实现图片存储与定时清理

基于SpringBoot + 七牛云 + Quartz实现图片存储与定时清理

2026年04月12日 Java 我要评论
一、图片存储方案1.1 常见图片存储方案实际项目中会拆分不同功能服务器,提升系统运行效率,图片存储常用三种方案:nginx 搭建图片服务器分布式文件存储系统(fastdfs、hdfs)云存储(阿里云

一、图片存储方案

1.1 常见图片存储方案

实际项目中会拆分不同功能服务器,提升系统运行效率,图片存储常用三种方案:

  1. nginx 搭建图片服务器
  2. 分布式文件存储系统(fastdfs、hdfs)
  3. 云存储(阿里云 oss、七牛云)

本文选用七牛云对象存储,接入简单、cdn 加速快、适合中小项目快速落地。

1.2 七牛云使用流程

1.2.1 注册与实名认证

  1. 访问七牛云官网:https://www.qiniu.com/
  2. 注册账号并完成个人实名认证(创建存储空间必须认证)

1.2.2 新建存储空间

控制台进入对象存储 kodo

  1. 创建存储空间(bucket):
    • 名称:3~63 位小写字母 / 数字 / 短横线
    • 存储区域:华东 / 华北 / 华南等
    • 访问控制:公开 / 私有(图片通常设为公开)

  1. 创建成功后可在文件管理查看上传资源。

1.2.3 获取 ak/sk 密钥

  1. 进入个人中心 → 密钥管理
  2. 复制 accesskeysecretkey(java sdk 鉴权使用)

1.3 java sdk 接入七牛云

1.3.1 引入 maven 依赖

<!-- 七牛云sdk -->
<dependency>
    <groupid>com.qiniu</groupid>
    <artifactid>qiniu-java-sdk</artifactid>
    <version>7.7.0</version>
</dependency>

1.3.2 封装七牛云工具类

将上传、删除封装为工具类,放入公共模块(ican-common):

public class qiniuutils {
    public static string accesskey = "你的ak";
    public static string secretkey = "你的sk";
    public static string bucket = "你的存储空间名";
    // 文件路径上传
    public static void upload2qiniu(string filepath,string filename){
        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) {
            ex.printstacktrace();
        }
    }
    // 字节数组上传
    public static void upload2qiniu(byte[] bytes, string filename){
        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(bytes, filename, uptoken);
            defaultputret putret = new gson().fromjson(response.bodystring(), defaultputret.class);
        } catch (qiniuexception ex) {
            ex.printstacktrace();
        }
    }
    // 删除文件
    public static void deletefilefromqiniu(string filename){
        configuration cfg = new configuration(zone.zone2());
        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());
        }
    }
}
​

二、新增套餐功能(图片上传 + 多对多关联)

2.1 需求说明

套餐是检查组的集合,套餐与检查组为多对多关系,需中间表t_setmeal_checkgroup关联。新增套餐需录入:

  • 基本信息(编码、名称、价格、图片等)
  • 关联检查组

2.2 前端实现(vue+elementui)

2.2.1 弹出新增窗口

点击新建按钮,清空表单并展示弹窗,同时加载所有检查组:

handlecreate(){
  this.resetform();
  this.dialogformvisible = true;
  // 查询所有检查组
  axios.get("/checkgroup/findall.do").then((res)=>{
    if(res.data.flag){
      this.tabledata = res.data.data;
    }else{
      this.$message.error(res.data.message);
    }
  });
}

2.2.2 图片上传与预览

使用el-upload组件,限制 jpg 格式、大小≤2mb:

<el-upload
  class="avatar-uploader"
  action="/setmeal/upload.do"
  :auto-upload="autoupload"
  name="imgfile"
  :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>
</el-upload>

上传前校验:

beforeavatarupload(file){
  const isjpg = file.type === 'image/jpeg';
  const islt2m = file.size / 1024 / 1024 < 2;
  if(!isjpg) this.$message.error("只能上传jpg格式!");
  if(!islt2m) this.$message.error("图片大小不能超过2mb!");
  return isjpg && islt2m;
}

2.3 后端实现

2.3.1 图片上传接口

@controller
@requestmapping("/setmeal")
public class setmealcontroller {
    @autowired
    private jedispool jedispool;

    // 图片上传
    @requestmapping("/upload")
    @responsebody
    public result upload(@requestparam("imgfile") multipartfile imgfile){
        try {
            string originalfilename = imgfile.getoriginalfilename();
            string extention = originalfilename.substring(originalfilename.lastindexof("."));
            string filename = uuid.randomuuid().tostring() + extention;
            // 上传七牛云
            qiniuutils.upload2qiniu(imgfile.getbytes(),filename);
            // 存入redis(所有上传图片)
            jedispool.getresource().sadd(redisconstant.setmeal_pic_resources,filename);
            return new result(true, messageconstant.pic_upload_success,filename);
        } catch (exception e) {
            e.printstacktrace();
            return new result(false, messageconstant.pic_upload_fail);
        }
    }
}

2.3.2 新增套餐(事务 + 多对多关联)

@service
@transactional
public class setmealserviceimpl implements setmealservice {
    @autowired
    private setmealdao setmealdao;

    @override
    public void add(setmeal setmeal, integer[] checkgroupids) {
        // 新增套餐基本信息
        setmealdao.add(setmeal);
        integer setmealid = setmeal.getid();
        // 设置套餐与检查组关联
        this.setsetmealandcheckgroup(setmealid,checkgroupids);
    }

    // 维护多对多关系
    private void setsetmealandcheckgroup(integer setmealid, integer[] checkgroupids) {
        if(checkgroupids != null && checkgroupids.length > 0){
            for (integer checkgroupid : checkgroupids) {
                map<string,integer> map = new hashmap<>();
                map.put("setmealid",setmealid);
                map.put("checkgroupid",checkgroupid);
                setmealdao.setsetmealandcheckgroup(map);
            }
        }
    }
}

2.3.3 保存套餐后同步 redis

@requestmapping("/add")
@responsebody
public result add(@requestbody setmeal setmeal, integer[] checkgroupids){
    try {
        setmealservice.add(setmeal,checkgroupids);
        // 存入redis(已保存到数据库的图片)
        jedispool.getresource().sadd(redisconstant.setmeal_pic_db_resources,setmeal.getimg());
        return new result(true, messageconstant.add_setmeal_success);
    }catch (exception e){
        e.printstacktrace();
        return new result(false, messageconstant.add_setmeal_fail);
    }
}

三、定时任务组件 quartz(重点)

3.1 quartz 核心概念

  1. job:要执行的任务(清理图片)
  2. trigger:触发器(定义执行时间)
  3. scheduler:调度器(绑定任务与触发器)

3.2 cron 表达式

格式:秒 分 时 日 月 周 年(年可省略)常用示例:

  • 0/1 * * * * ?:每秒执行
  • 0 0 2 * * ?:每天凌晨 2 点执行
  • 0 0 0/1 * * ?:每小时执行

示例:

前面介绍了cron表达式,但是自己编写表达式还是有一些困难的,我们可以借助一些 cron表达式在线生成器来根据我们的需求生成表达式即可。

http://cron.qqe2.com/

3.3 springboot 整合 quartz

3.3.1 引入依赖

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-quartz</artifactid>
</dependency>

3.3.2 配置类

@configuration
public class quartzconfig {
    @bean    //job:干什么事
    public methodinvokingjobdetailfactorybean jobdetail(clearimgjob clearimgjob){
        methodinvokingjobdetailfactorybean bean = new methodinvokingjobdetailfactorybean();
        bean.settargetobject(clearimgjob);
        bean.settargetmethod("clearimg");
        return bean;
    }

    @bean    //trigger:什么时候
    public crontriggerfactorybean trigger(methodinvokingjobdetailfactorybean jobdetail){
        crontriggerfactorybean bean = new crontriggerfactorybean();
        bean.setcronexpression("0 0 2 * * ?"); // 每天凌晨2点
        bean.setjobdetail(jobdetail.getobject());
        return bean;
    }

    @bean    //scheduler:什么时候干什么事
    public schedulerfactorybean scheduler(crontriggerfactorybean trigger){
        schedulerfactorybean bean = new schedulerfactorybean();
        bean.settriggers(trigger.getobject());
        return bean;
    }
}

​

四、定时清理垃圾图片(核心)

4.1 垃圾图片产生原因

用户上传图片后未提交套餐,图片存于七牛云但无数据库记录,成为垃圾文件。

4.2 清理思路

  1. redis 集合 a:setmealpicresources(所有上传图片)
  2. redis 集合 b:setmealpicdbresources(已保存数据库图片)
  3. 求差集:a - b = 垃圾图片
  4. 定时删除七牛云 + redis 中的垃圾文件

4.3 清理任务实现

@component
public class clearimgjob {
    @autowired
    private jedispool jedispool;

    public void clearimg(){
        // 计算差集
        set<string> garbageimg = jedispool.getresource().sdiff(
                redisconstant.setmeal_pic_resources,
                redisconstant.setmeal_pic_db_resources);

        if(garbageimg != null){
            for (string imgname : garbageimg) {
                // 删除七牛云文件
                qiniuutils.deletefilefromqiniu(imgname);
                // 删除redis记录
                jedispool.getresource().srem(redisconstant.setmeal_pic_resources,imgname);
                system.out.println("清理垃圾图片:" + imgname);
            }
        }
    }
}

​

五、总结

  1. 图片存储:选用七牛云对象存储,接入简单、cdn 加速、支持 java sdk。
  2. 套餐管理:多对多关联检查组,支持图片上传预览、分页查询。
  3. 垃圾清理:基于 redis 集合差集定位垃圾图片,quartz 定时自动清理,节省存储资源。

本文完整实现预约系统套餐管理的图片存储与定时清理,可直接复用至同类项目。

以上就是基于springboot + 七牛云 + quartz实现图片存储与定时清理的详细内容,更多关于springboot七牛云图片存储与定时清理的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com