1、首先解析一下,图片上传分为两个步骤
- 第一次上传提交到后台,保存成功后,会返回一个路径
- 第二次提交是图片路径和其他信息一起提交到后台保存
由此可见,当第一步执行成功后,当第二步出现某些原因提交不了,这时第一步中上传的图片就没用了,此时为垃圾图片,对于这些图片就没必要继续保存了
2、对于上面这种情况,设计如下方案:
(下面的方案只列举 【路径和其他信息保存时】新增情况,其他,如修改,删除,根据实际情况举一反三即可)
创建maven工程,不会的百度即可
-
简单介绍 quartz和cros表达式
Quartz是Job scheduling(作业调度)领域的一个开源项目,Quartz既可以单独使用也可以跟spring框架整合使用,在实际开发中一般会使用后者。使用Quartz可以开发一个 或者多个定时任务,每个定时任务可以单独指定执行的时间,例如每隔1小时执行一次、 每个月第一天上午10点执行一次、每个月最后一天下午5点执行一次等
cros表达式:0/10 * * * * ?,具体学习网上百度就能知道可
cros表达式在线生成 -
加入maven依赖
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
- 配置web.xml文件
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- 创建spring配置文件
(1)applicationContext-redis.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--Jedis连接池的相关配置-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal">
<value>200</value>
</property>
<property name="maxIdle">
<value>50</value>
</property>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
</bean>
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="poolConfig" ref="jedisPoolConfig" />
<constructor-arg name="host" value="192.168.1.19" />
<constructor-arg name="port" value="6379" type="int" />
<constructor-arg name="timeout" value="30000" type="int" />
</bean>
</beans>
(2)applicationContext-jobs.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--开启spring注解使用-->
<context:annotation-config></context:annotation-config>
<!--注册自定义Job-->
<bean id="clearImgJob" class="com.zeny.jobs.ClearImgJob"></bean>
<bean id="jobDetail"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 注入目标对象 -->
<property name="targetObject" ref="clearImgJob"/>
<!-- 注入目标方法 -->
<property name="targetMethod" value="clearImg"/>
</bean>
<!-- 注册一个触发器,指定任务触发的时间 -->
<bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- 注入JobDetail -->
<property name="jobDetail" ref="jobDetail"/>
<!-- 指定触发的时间,基于Cron表达式 -->
<property name="cronExpression">
<!--
<value>0 0 2 * * ?</value>
-->
<value>0/30 * * * * ?</value>
</property>
</bean>
<!-- 注册一个统一的调度工厂,通过这个调度工厂调度任务 -->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 注入多个触发器 -->
<property name="triggers">
<list>
<ref bean="myTrigger"/>
</list>
</property>
</bean>
</beans>
- 创建clearImgJob
package com.zeny.jobs;
import com.zeny.constant.RedisConstant;
import com.zeny.util.QiniuUtils;
import org.springframework.beans.factory.annotation.Autowired;
import redis.clients.jedis.JedisPool;
import java.util.Set;
public class ClearImgJob {
@Autowired
private JedisPool jedisPool;
public void clearImg() {
//sdiff(大集合,小集合) 计算差值
Set<String> set = jedisPool.getResource().sdiff(RedisConstant.SETMEAL_PIC_RESOURCES, RedisConstant.SETMEAL_PIC_DB_RESOURCES);
if (set != null) {
for (String picName : set) {
//删除七牛云服务器的图片
QiniuUtils.deleteFileFromQiniu(picName);
//从Redis集合中删除图片的名称
jedisPool.getResource().srem(RedisConstant.SETMEAL_PIC_RESOURCES, picName);
System.out.println("定时删除垃圾图片: " + picName);
}
}
}
}
Redis常量类:
public class RedisConstant {
//图片所有图片名称
public static final String SETMEAL_PIC_RESOURCES = "setmealPicResources";
//图片保存在数据库中的图片名称
public static final String SETMEAL_PIC_DB_RESOURCES = "setmealPicDbResources";
}
- 搞定
- 分析
第一次图片上传成功后,把返回路径图片名称(图片名称不重复)存入Redis中,即为Redis常量类中的SETMEAL_PIC_RESOURCES
中
第二次成功保存信息后再把图片名称存入Redis中,即为Redis常量类中的SETMEAL_PIC_DB_RESOURCES
中,计算差值,即为垃圾图片,定时删除