本文由黑壳网发布
本文来源 Quartz 定时邮件发送备份文件 - 黑壳网 http://www.bhusk.com/articles/2017/07/27/1501146724360.html
壳叔搞笑一刻

正文
之前由于黑壳网的博客数据库,一直没有做定期备份的处理,虽然现在不一定会出问题,但起码数据备份意识上还是要有的。
之前有考虑过用七牛云等第三方服务,但是最后由于种种原因,暂时不考虑用第三方服务。
所以自己手写了一个定时备份程序,简单的思路 ↓
到达指定时间,将数据库备份文件发送利用邮箱,发送至指定邮箱,达到定期备份的目的。
特别提示:如果文件对安全性要求很高的话,不推荐
程序采用 Java 语言和maven 强大的依赖体系+流行的 spring,为什么要用 Java,只是写着好玩不要太较真了。
项目代码
pom.xml 文件
Quartz 的包是整个项目不可缺少的
<properties> <!-- Spring的版本 --> <springframework.version>4.0.6.RELEASE</springframework.version> <!-- Quartz的版本 --> <quartz.version>2.2.1</quartz.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>${quartz.version}</version> </dependency> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springframework.version}</version> </dependency> </dependencies>
MyJob.java 继承 QuartzJobBean 然后 Override
有钻研精神的可以一点一点扒代码看 QuartzJobBean 。
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.quartz.QuartzJobBean; import java.util.Date; /** * kzyuan Job 参考 * @description black husk * @description http://www.bhusk.com */ public class MyJob extends QuartzJobBean { private static Logger logger = LoggerFactory.getLogger(DatabaseBackupJob.class); @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { System.out.println("执行时间:"+new Date()); } }
application.xml 可以理解为 quartz 配置文件 注释很齐全
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 定义任务bean --> <bean name="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- 指定具体的job类 --> <property name="jobClass" value="com.bhusk.quartz.Job.MyJob"/> <!-- 指定job的名称 --> <property name="name" value="myJob"/> <!-- 指定job的分组 --> <property name="group" value="jobs"/> <!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中删除该任务 --> <property name="durability" value="true"/> <!-- 指定spring容器的key,如果不设定在job中的jobmap中是获取不到spring容器的 --> <property name="applicationContextJobDataKey" value="applicationContext"/> </bean> <!-- 定义触发器 --> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="myJobDetail"/> <!--执行时间 --> <property name="cronExpression" value="0 0 3 * * ?"/> </bean> <!-- 定义触发器 --> <!--演示:一个job可以有多个trigger; --> <!--<bean id="cronTrigger2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">--> <!--<property name="jobDetail" ref="myJobDetail2" />--> <!--每一分钟执行一次--> <!-- <property name="cronExpression" value="0 0 3 * * ?"/> --> <!--</bean>--> <!-- 定义调度器 --> <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger"/> <!-- <ref bean="cronTrigger2"/> --> </list> </property> </bean> </beans>
JavaMail 发送邮件工具类
java 实现邮件的发送, 抄送及多附件
这个工具类来源网络,具体精准位置也不清楚了
import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import javax.mail.internet.MimeUtility; import java.io.UnsupportedEncodingException; import java.util.Properties; /** * 邮件管理器 * java 实现邮件的发送, 抄送及多附件 */ public class EmailManager { public static String username = "keshu@bhusk.com"; // 服务邮箱(from邮箱) public static String password = ""; // 邮箱密码 public static String senderNick = "黑壳网的壳叔"; // 发件人昵称 private Properties props; // 系统属性 private Session session; // 邮件会话对象 private MimeMessage mimeMsg; // MIME邮件对象 private Multipart mp; // Multipart对象,邮件内容,标题,附件等内容均添加到其中后再生成MimeMessage对象 private static EmailManager instance = null; public EmailManager() { props = System.getProperties(); props.put("mail.smtp.auth", "true"); props.put("mail.transport.protocol", "smtp"); props.put("mail.smtp.host", "smtp.163.com"); props.put("mail.smtp.port", "25"); props.put("username", username); props.put("password", password); // 建立会话 session = Session.getDefaultInstance(props); session.setDebug(false); } public static EmailManager getInstance() { if (instance == null) { instance = new EmailManager(); } return instance; } /** * 发送邮件 * * @param from 发件人 * @param to 收件人 * @param copyto 抄送 * @param subject 主题 * @param content 内容 * @param fileList 附件列表 * @return */ public boolean sendMail(String from, String[] to, String[] copyto, String subject, String content, String[] fileList) { boolean success = true; try { mimeMsg = new MimeMessage(session); mp = new MimeMultipart(); // 自定义发件人昵称 String nick = ""; try { nick = javax.mail.internet.MimeUtility.encodeText(senderNick); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // 设置发件人 // mimeMsg.setFrom(new InternetAddress(from)); mimeMsg.setFrom(new InternetAddress(from, nick)); // 设置收件人 if (to != null && to.length > 0) { String toListStr = getMailList(to); mimeMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(toListStr)); } // 设置抄送人 if (copyto != null && copyto.length > 0) { String ccListStr = getMailList(copyto); mimeMsg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccListStr)); } // 设置主题 mimeMsg.setSubject(subject); // 设置正文 BodyPart bp = new MimeBodyPart(); bp.setContent(content, "text/html;charset=utf-8"); mp.addBodyPart(bp); // 设置附件 if (fileList != null && fileList.length > 0) { for (int i = 0; i < fileList.length; i++) { bp = new MimeBodyPart(); FileDataSource fds = new FileDataSource(fileList[i]); bp.setDataHandler(new DataHandler(fds)); bp.setFileName(MimeUtility.encodeText(fds.getName(), "UTF-8", "B")); mp.addBodyPart(bp); } } mimeMsg.setContent(mp); mimeMsg.saveChanges(); // 发送邮件 if (props.get("mail.smtp.auth").equals("true")) { Transport transport = session.getTransport("smtp"); transport.connect((String) props.get("mail.smtp.host"), (String) props.get("username"), (String) props.get("password")); // transport.sendMessage(mimeMsg, mimeMsg.getRecipients(Message.RecipientType.TO)); // transport.sendMessage(mimeMsg, mimeMsg.getRecipients(Message.RecipientType.CC)); transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients()); transport.close(); } else { Transport.send(mimeMsg); } System.out.println("邮件发送成功"); } catch (MessagingException e) { e.printStackTrace(); success = false; } catch (UnsupportedEncodingException e) { e.printStackTrace(); success = false; } return success; } /** * 发送邮件 * * @param from 发件人 * @param to 收件人, 多个Email以英文逗号分隔 * @param cc 抄送, 多个Email以英文逗号分隔 * @param subject 主题 * @param content 内容 * @param fileList 附件列表 * @return */ public boolean sendMail(String from, String to, String cc, String subject, String content, String[] fileList) { boolean success = true; try { mimeMsg = new MimeMessage(session); mp = new MimeMultipart(); // 自定义发件人昵称 String nick = ""; try { nick = javax.mail.internet.MimeUtility.encodeText(senderNick); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } // 设置发件人 // mimeMsg.setFrom(new InternetAddress(from)); mimeMsg.setFrom(new InternetAddress(from, nick)); // 设置收件人 if (to != null && to.length() > 0) { mimeMsg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); } // 设置抄送人 if (cc != null && cc.length() > 0) { mimeMsg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc)); } // 设置主题 mimeMsg.setSubject(subject); // 设置正文 BodyPart bp = new MimeBodyPart(); bp.setContent(content, "text/html;charset=utf-8"); mp.addBodyPart(bp); // 设置附件 if (fileList != null && fileList.length > 0) { for (int i = 0; i < fileList.length; i++) { bp = new MimeBodyPart(); FileDataSource fds = new FileDataSource(fileList[i]); bp.setDataHandler(new DataHandler(fds)); bp.setFileName(MimeUtility.encodeText(fds.getName(), "UTF-8", "B")); mp.addBodyPart(bp); } } mimeMsg.setContent(mp); mimeMsg.saveChanges(); // 发送邮件 if (props.get("mail.smtp.auth").equals("true")) { Transport transport = session.getTransport("smtp"); transport.connect((String) props.get("mail.smtp.host"), (String) props.get("username"), (String) props.get("password")); transport.sendMessage(mimeMsg, mimeMsg.getAllRecipients()); transport.close(); } else { Transport.send(mimeMsg); } System.out.println("邮件发送成功"); } catch (MessagingException e) { e.printStackTrace(); success = false; } catch (UnsupportedEncodingException e) { e.printStackTrace(); success = false; } return success; } public String getMailList(String[] mailArray) { StringBuffer toList = new StringBuffer(); int length = mailArray.length; if (mailArray != null && length < 2) { toList.append(mailArray[0]); } else { for (int i = 0; i < length; i++) { toList.append(mailArray[i]); if (i != (length - 1)) { toList.append(","); } } } return toList.toString(); } public static void main(String[] args) { String from = username; String[] to = {"keshu@bhusk.com", "1520812121@qq.com"}; String[] copyto = {"lu12121@qq.com"}; String subject = "黑壳网数据库备份"; String content = "没有数据就没有一切,数据库备份就是一种防范灾难于未然的强力手段,没有了数据,应用再花哨也是镜中花水中月。"; String[] fileList = new String[2]; fileList[0] = "~/solo_h2/db.mv.db"; fileList[1] = "~/solo_h2/db.trace.db"; EmailManager.getInstance().sendMail(from, to, copyto, subject, content, fileList); } }
参考项目 GitHub
参考项目 GitHub:https://github.com/ykz200/Quartz_DatabaseBackup
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于