最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于SpringBoot + 七牛云 + Quartz實現(xiàn)圖片存儲與定時清理

 更新時間:2026年04月12日 14:13:43   作者:小旭9527  
這篇文章主要介紹了在實際項目中使用七牛云對象存儲進行圖片存儲的方法,以及如何實現(xiàn)套餐管理(包括圖片上傳和多對多關(guān)聯(lián)檢查組)的前端和后端功能,此外,還詳細講解了如何使用Quartz定時任務(wù)組件自動清理垃圾圖片,以節(jié)省存儲資源,需要的朋友可以參考下

一、圖片存儲方案

1.1 常見圖片存儲方案

實際項目中會拆分不同功能服務(wù)器,提升系統(tǒng)運行效率,圖片存儲常用三種方案:

  1. Nginx 搭建圖片服務(wù)器
  2. 分布式文件存儲系統(tǒng)(FastDFS、HDFS)
  3. 云存儲(阿里云 OSS、七牛云)

本文選用七牛云對象存儲,接入簡單、CDN 加速快、適合中小項目快速落地。

1.2 七牛云使用流程

1.2.1 注冊與實名認證

  1. 訪問七牛云官網(wǎng):https://www.qiniu.com/
  2. 注冊賬號并完成個人實名認證(創(chuàng)建存儲空間必須認證)

1.2.2 新建存儲空間

控制臺進入對象存儲 KODO

  1. 創(chuàng)建存儲空間(Bucket):
    • 名稱:3~63 位小寫字母 / 數(shù)字 / 短橫線
    • 存儲區(qū)域:華東 / 華北 / 華南等
    • 訪問控制:公開 / 私有(圖片通常設(shè)為公開)

  1. 創(chuàng)建成功后可在文件管理查看上傳資源。

1.2.3 獲取 AK/SK 密鑰

  1. 進入個人中心 → 密鑰管理
  2. 復(fù)制 AccessKeySecretKey(Java SDK 鑒權(quán)使用)

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()); //你自己存儲空間的存儲區(qū)域
        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();
        }
    }
    // 字節(jié)數(shù)組上傳
    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());
        }
    }
}
?

二、新增套餐功能(圖片上傳 + 多對多關(guān)聯(lián))

2.1 需求說明

套餐是檢查組的集合,套餐與檢查組為多對多關(guān)系,需中間表t_setmeal_checkgroup關(guān)聯(lián)。新增套餐需錄入:

  • 基本信息(編碼、名稱、價格、圖片等)
  • 關(guān)聯(lián)檢查組

2.2 前端實現(xiàn)(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 圖片上傳與預(yù)覽

使用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 后端實現(xiàn)

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 新增套餐(事務(wù) + 多對多關(guān)聯(lián))

@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();
        // 設(shè)置套餐與檢查組關(guān)聯(lián)
        this.setSetmealAndCheckgroup(setmealId,checkgroupIds);
    }

    // 維護多對多關(guān)系
    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(已保存到數(shù)據(jù)庫的圖片)
        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);
    }
}

三、定時任務(wù)組件 Quartz(重點)

3.1 Quartz 核心概念

  1. Job:要執(zhí)行的任務(wù)(清理圖片)
  2. Trigger:觸發(fā)器(定義執(zhí)行時間)
  3. Scheduler:調(diào)度器(綁定任務(wù)與觸發(fā)器)

3.2 Cron 表達式

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

  • 0/1 * * * * ?:每秒執(zhí)行
  • 0 0 2 * * ?:每天凌晨 2 點執(zhí)行
  • 0 0 0/1 * * ?:每小時執(zhí)行

示例:

前面介紹了cron表達式,但是自己編寫表達式還是有一些困難的,我們可以借助一些 cron表達式在線生成器來根據(jù)我們的需求生成表達式即可。

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 垃圾圖片產(chǎn)生原因

用戶上傳圖片后未提交套餐,圖片存于七牛云但無數(shù)據(jù)庫記錄,成為垃圾文件。

4.2 清理思路

  1. Redis 集合 A:setmealPicResources(所有上傳圖片)
  2. Redis 集合 B:setmealPicDbResources(已保存數(shù)據(jù)庫圖片)
  3. 求差集:A - B = 垃圾圖片
  4. 定時刪除七牛云 + Redis 中的垃圾文件

4.3 清理任務(wù)實現(xiàn)

@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);
            }
        }
    }
}

?

五、總結(jié)

  1. 圖片存儲:選用七牛云對象存儲,接入簡單、CDN 加速、支持 Java SDK。
  2. 套餐管理:多對多關(guān)聯(lián)檢查組,支持圖片上傳預(yù)覽、分頁查詢。
  3. 垃圾清理:基于 Redis 集合差集定位垃圾圖片,Quartz 定時自動清理,節(jié)省存儲資源。

本文完整實現(xiàn)預(yù)約系統(tǒng)套餐管理的圖片存儲與定時清理,可直接復(fù)用至同類項目。

以上就是基于SpringBoot + 七牛云 + Quartz實現(xiàn)圖片存儲與定時清理的詳細內(nèi)容,更多關(guān)于SpringBoot七牛云圖片存儲與定時清理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解設(shè)計模式中的proxy代理模式及在Java程序中的實現(xiàn)

    詳解設(shè)計模式中的proxy代理模式及在Java程序中的實現(xiàn)

    代理模式主要分為靜態(tài)代理和動態(tài)代理,使客戶端方面的使用者通過設(shè)置的代理來操作對象,下面來詳解設(shè)計模式中的proxy代理模式及在Java程序中的實現(xiàn)
    2016-05-05
  • Java中字符串轉(zhuǎn)時間與時間轉(zhuǎn)字符串的操作詳解

    Java中字符串轉(zhuǎn)時間與時間轉(zhuǎn)字符串的操作詳解

    Java 的 java.time 包提供了強大的日期和時間處理功能,通過 DateTimeFormatter 可以輕松地在日期時間對象和字符串之間進行轉(zhuǎn)換,下面小編給大家詳細介紹一下Java中字符串轉(zhuǎn)時間與時間轉(zhuǎn)字符串的操作,需要的朋友可以參考下
    2025-04-04
  • jmeter中beanshell的用法小結(jié)

    jmeter中beanshell的用法小結(jié)

    本文主要介紹了jmeter中beanshell的用法小結(jié),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • IntelliJ IDEA新版本中Maven子模塊不顯示的解決方案

    IntelliJ IDEA新版本中Maven子模塊不顯示的解決方案

    在使用IntelliJ IDEA 2024版本開發(fā)Maven多模塊項目時,我發(fā)現(xiàn)一個令人困惑的現(xiàn)象,父模塊的子模塊未在右側(cè) Maven 工具窗口中顯示,僅顯示父模塊名稱,而此前2021版本中,父模塊和子模塊均能正常顯示,所以本文給大家介紹了IntelliJ IDEA新版本中Maven子模塊不顯示的解決方案
    2025-05-05
  • Java利用隨機分錢模擬財富變化

    Java利用隨機分錢模擬財富變化

    這篇文章主要為大家詳細介紹了Java如何利用隨機分錢思想模擬財富的變化,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-12-12
  • Spring MVC 更靈活的控制 json 返回問題(自定義過濾字段)

    Spring MVC 更靈活的控制 json 返回問題(自定義過濾字段)

    本篇文章主要介紹了Spring MVC 更靈活的控制 json 返回問題(自定義過濾字段),具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • Mapper報錯@MapKey is required問題及解決方式

    Mapper報錯@MapKey is required問題及解決方式

    這段描述主要討論了在使用MyBatis或類似框架時遇到@MapKeyisrequired錯誤的常見原因及解決方法,包括MapKey注解的正確使用以及相關(guān)配置檢查,特別強調(diào)了正確配置isMapMapKey和ResultMap注解對于避免數(shù)據(jù)不一致和運行時異常的重要性
    2026-06-06
  • 深入了解MyBatis參數(shù)

    深入了解MyBatis參數(shù)

    今天小編就為大家分享一篇關(guān)于深入了解MyBatis參數(shù),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • Java Applet查找素數(shù)小程序代碼實例

    Java Applet查找素數(shù)小程序代碼實例

    這篇文章主要介紹了Java Applet查找素數(shù)小程序代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • Springboot攔截filter中異常的處理

    Springboot攔截filter中異常的處理

    SpringBoot提供了全局異常處理機制可以攔截所有異常,包括Filter中的異常,本文主要介紹了Springboot攔截filter中異常的處理,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11

最新評論

江川县| 博野县| 临湘市| 富裕县| 兴义市| 华池县| 潢川县| 石泉县| 太和县| 香河县| 西华县| 莒南县| 防城港市| 兴安盟| 包头市| 钟山县| 合江县| 汾阳市| 乌审旗| 成安县| 府谷县| 邯郸市| 伽师县| 炎陵县| 威海市| 溧阳市| 简阳市| 宁德市| 棋牌| 拜城县| 枣庄市| 青河县| 丰都县| 太谷县| 邓州市| 尚义县| 毕节市| 临泽县| 灵川县| 余干县| 金阳县|