zoukankan      html  css  js  c++  java
  • springboot备份mysql后发送邮件并删除备份文件,支持win和Linux

    首先加入springboot的邮箱依赖

    <!--邮箱依赖-->
    <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-mail -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>

    邮件实体类

     1 package com.xiaostudy.shiro_test1.entity;
     2 
     3 import java.io.File;
     4 
     5 /**
     6  * Created with IntelliJ IDEA.
     7  * User: xiaostudy
     8  * Date: 2019/7/23
     9  * Time: 21:28
    10  * Description: No Description
    11  */
    12 public class MailEntity {
    13     /**
    14      * 主题
    15      */
    16     private String subject;
    17     /**
    18      * 内容
    19      */
    20     private String content;
    21     /**
    22      * 邮箱
    23      */
    24     private String toAccount;
    25     /**
    26      * 附件
    27      */
    28     private File attachmentFile;
    29     /**
    30      * 附件文件名
    31      */
    32     private String attachmentFileName;
    33 
    34     public String getSubject() {
    35         return subject;
    36     }
    37 
    38     public void setSubject(String subject) {
    39         this.subject = subject;
    40     }
    41 
    42     public String getContent() {
    43         return content;
    44     }
    45 
    46     public void setContent(String content) {
    47         this.content = content;
    48     }
    49 
    50     public String getToAccount() {
    51         return toAccount;
    52     }
    53 
    54     public void setToAccount(String toAccount) {
    55         this.toAccount = toAccount;
    56     }
    57 
    58     public File getAttachmentFile() {
    59         return attachmentFile;
    60     }
    61 
    62     public void setAttachmentFile(File attachmentFile) {
    63         this.attachmentFile = attachmentFile;
    64     }
    65 
    66     public String getAttachmentFileName() {
    67         return attachmentFileName;
    68     }
    69 
    70     public void setAttachmentFileName(String attachmentFileName) {
    71         this.attachmentFileName = attachmentFileName;
    72     }
    73 }

    spring获取bean工具类【不是service和controller层的不能注入bean】

      1 package com.xiaostudy.shiro_test1.utils;
      2 
      3 import org.springframework.beans.BeansException;
      4 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
      5 import org.springframework.context.ApplicationContext;
      6 import org.springframework.context.ApplicationContextAware;
      7 import org.springframework.stereotype.Component;
      8 
      9 import java.util.Map;
     10 
     11 /**
     12  * Spring Context 工具类:可以在其他地方通过静态方法获取Spring配置的Bean
     13  *
     14  */
     15 @Component
     16 public class SpringContextUtils implements ApplicationContextAware {
     17     private static ApplicationContext applicationContext;
     18 
     19     @Override
     20     public void setApplicationContext(ApplicationContext applicationContext)
     21             throws BeansException {
     22         if (SpringContextUtils.applicationContext == null) {
     23             SpringContextUtils.applicationContext = applicationContext;
     24         }
     25     }
     26 
     27     public static ApplicationContext getApplicationContext() {
     28         return applicationContext;
     29     }
     30 
     31     public static Object getBean(String name) {
     32         return applicationContext.getBean(name);
     33     }
     34 
     35     /**
     36      * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
     37      */
     38     public static <T> T getBean(Class<T> requiredType) {
     39 //        assertContextInjected();
     40         if(null == applicationContext) {
     41             return null;
     42         }
     43         return applicationContext.getBean(requiredType);
     44     }
     45 
     46     /**
     47      * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
     48      */
     49     public static <T> Map<String, T> getBeanOfMap(Class<T> requiredType) {
     50 //        assertContextInjected();
     51         if(null == applicationContext) {
     52             return null;
     53         }
     54         return applicationContext.getBeansOfType(requiredType);
     55     }
     56 
     57     /**
     58      * 检查ApplicationContext不为空.
     59      */
     60     /*private static void assertContextInjected() {
     61         Validate.validState(applicationContext != null, "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.");
     62     }*/
     63 
     64     /***
     65      * 类似于getBean(String name)只是在参数中提供了需要返回到的类型。
     66      *
     67      * @param name
     68      * @param requiredType
     69      * @return
     70      * @throws BeansException
     71      */
     72     public static <T> T getBean(String name, Class<T> requiredType) {
     73         return applicationContext.getBean(name, requiredType);
     74     }
     75 
     76     /**
     77      * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
     78      *
     79      * @param name
     80      * @return boolean
     81      */
     82     public static boolean containsBean(String name) {
     83         return applicationContext.containsBean(name);
     84     }
     85 
     86     /**
     87      * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
     88      * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
     89      *
     90      * @param name
     91      * @return boolean
     92      * @throws NoSuchBeanDefinitionException
     93      */
     94     public static boolean isSingleton(String name) {
     95         return applicationContext.isSingleton(name);
     96     }
     97 
     98     public static Class<? extends Object> getType(String name) {
     99         return applicationContext.getType(name);
    100     }
    101 
    102     /**
    103      * 获取Spring装配的bean的名称
    104      */
    105     public static String[] getBeanNameAll() {
    106         return applicationContext.getBeanDefinitionNames();
    107     }
    108 
    109     /***
    110      * 类似于获取同类型的BEAN
    111      * @param <T>
    112      * @param requiredType
    113      * @return
    114      * @throws BeansException
    115      */
    116     public static <T> Map<String, T> getBeansOfType(Class<T> requiredType) {
    117         return applicationContext.getBeansOfType(requiredType);
    118     }
    119 }

    发邮件工具类

     1 package com.xiaostudy.shiro_test1.utils;
     2 
     3 import com.xiaostudy.shiro_test1.entity.MailEntity;
     4 //import org.jasypt.encryption.StringEncryptor;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.boot.autoconfigure.mail.MailProperties;
     7 import org.springframework.mail.SimpleMailMessage;
     8 import org.springframework.mail.javamail.JavaMailSender;
     9 import org.springframework.mail.javamail.MimeMessageHelper;
    10 import org.springframework.stereotype.Component;
    11 
    12 import javax.mail.MessagingException;
    13 import javax.mail.internet.MimeMessage;
    14 
    15 /**
    16  * Created with IntelliJ IDEA.
    17  * User: xiaostudy
    18  * Date: 2019/7/23
    19  * Time: 21:25
    20  * Description: No Description
    21  */
    22 @Component
    23 public class MailUtils {
    24 
    25     /**
    26      * 发送邮件,里面有判断是否发文件
    27      */
    28     public static void sendMail(MailEntity mailEntity) {
    29         if(null != mailEntity) {
    30             if(null != mailEntity.getAttachmentFile() && mailEntity.getAttachmentFile().exists()) {
    31                 if(null == mailEntity.getAttachmentFileName()) {
    32                     mailEntity.setAttachmentFileName(mailEntity.getAttachmentFile().getName());
    33                 }
    34                 sendMailAttachment(mailEntity);
    35             } else {
    36                 sendSimpleMail(mailEntity);
    37             }
    38         }
    39     }
    40 
    41     /**
    42      * 发送邮件,这里只发内容,不发文件
    43      */
    44     public static void sendSimpleMail(MailEntity mailEntity) {
    45         SimpleMailMessage mimeMessage = new SimpleMailMessage();
    46         mimeMessage.setFrom(SpringContextUtils.getBean(MailProperties.class).getUsername());
    47         mimeMessage.setTo(mailEntity.getToAccount());
    48         mimeMessage.setSubject(mailEntity.getSubject());
    49         mimeMessage.setText(mailEntity.getContent());
    50         SpringContextUtils.getBean(JavaMailSender.class).send(mimeMessage);
    51     }
    52 
    53     /**
    54      * 发送邮件-附件邮件
    55      *
    56      * @param mailEntity
    57      */
    58     public static boolean sendMailAttachment(MailEntity mailEntity) {
    59         JavaMailSender javaMailSender = SpringContextUtils.getBean(JavaMailSender.class);
    60         try {
    61             MimeMessage mimeMessage = javaMailSender.createMimeMessage();
    62             MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
    63             helper.setFrom(SpringContextUtils.getBean(MailProperties.class).getUsername());
    64             helper.setTo(mailEntity.getToAccount());
    65             helper.setSubject(mailEntity.getSubject());
    66             helper.setText(mailEntity.getContent(), true);
    67             // 增加附件名称和附件
    68             helper.addAttachment(mailEntity.getAttachmentFileName(), mailEntity.getAttachmentFile());
    69             javaMailSender.send(mimeMessage);
    70             return true;
    71         } catch (MessagingException e) {
    72             e.printStackTrace();
    73             return false;
    74         }
    75     }
    76 }

     删除备份文件线程类

     1 package com.xiaostudy.shiro_test1.thread;
     2 
     3 import com.xiaostudy.shiro_test1.entity.LoginLogEntity;
     4 import com.xiaostudy.shiro_test1.service.LoginLogService;
     5 import com.xiaostudy.shiro_test1.utils.DateUtils;
     6 import com.xiaostudy.shiro_test1.utils.IpUtil;
     7 import com.xiaostudy.shiro_test1.utils.MakeMD5;
     8 import com.xiaostudy.shiro_test1.utils.ShiroUtils;
     9 
    10 import java.io.File;
    11 
    12 /**
    13  * Created with IntelliJ IDEA.
    14  * User: xiaostudy
    15  * Date: 2019/7/22
    16  * Time: 0:05
    17  * Description: No Description
    18  */
    19 public class RemoveBackupSqlFileThread implements Runnable {
    20 
    21     private String filePath;
    22     private Long start;
    23 
    24     public RemoveBackupSqlFileThread(String filePath) {
    25         this.filePath = filePath;
    26         this.start = System.currentTimeMillis();
    27     }
    28 
    29     @Override
    30     public void run() {
    31         try {
    32             // 前让线程睡1分钟,保证邮件已经发送
    33             Thread.sleep(1000 * 60);
    34         } catch (InterruptedException e) {
    35             e.printStackTrace();
    36         }
    37         File file = new File(filePath);
    38         // 30分钟内,每1分钟删除备份文件,删除文件就结束线程
    39         while (System.currentTimeMillis() - this.start < 1000 * 60 * 30) {
    40             if(null != file && file.exists() && file.isFile() && file.delete()) {
    41                 break;
    42             }
    43             try {
    44                 Thread.sleep(1000 * 60);
    45             } catch (InterruptedException e) {
    46                 e.printStackTrace();
    47             }
    48         }
    49     }
    50 }

    1、在win下备份mysql并发送邮件

    在spirng:后加,如下图

    mail:
        host: smtp.mxhichina.com      #阿里云发送服务器地址
        port: 25                      #端口号
        username: 邮箱地址        #发送人地址
        password: 密码  #密码

    配置my.ini【因为java运行备份mysql的命令,不能直接用密码】

    在最后添加

    [client]
    host=localhost
    user=用户名
    password=密码

    这里说明一下这个my.ini文件,有些是在安装mysql的目录下,有些不是在安装目录下,可以用工具Everything搜一下

    备份的命令是

    "D:/Program Files/MySQL/MySQL Server 5.7/bin/mysqldump.exe" --defaults-extra-file="D:/ProgramData/MySQL/MySQL Server 5.7/my.ini" -B 数据库名称>C:/temp/20190725.sql

    上面为什么要用双引号呢,主要是文件夹名称有空格,cmd识别不了,加双引号就好了。

    备份数据,发送邮件,删除备份文件 

    @GetMapping("backup")
    @ResponseBody
    public Map backup(){
        String thisDateTime = DateUtils.getDateTime("yyyyMMdd_HHmmss");
        String filePath;
        String shell;
        String[] cmd;
        // 通过获取系统名称是否包含windows来判断是win还是Linux
        if(System.getProperties().getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1) {
            filePath = "C:/temp/myLog_" + thisDateTime + ".sql";
            shell = ""D:/Program Files/MySQL/MySQL Server 5.7/bin/mysqldump.exe" --defaults-extra-file="D:/ProgramData/MySQL/MySQL Server 5.7/my.ini" -B my_log>" + filePath;
            // java运行cmd命令要多加cmd空格/c空格
            shell = "cmd /c " + shell;
        } else {
            filePath = "/home/backup/myLog_" + thisDateTime + ".sql";
            shell = "/usr/local/mysql/bin/mysqldump --defaults-extra-file=/usr/local/mysql/my.cnf -B my_log>" + filePath;
        }
        System.out.println("shell:" + shell);
        Runtime runTime = Runtime.getRuntime();
        if (runTime == null) {
            System.err.println("Create runtime false!");
        }
        try {
            if(System.getProperties().getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1) {
                runTime.exec(shell);
            } else {
                runTime.exec(new String[]{"/bin/sh", "-c", shell});
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        MailEntity mailEntity = new MailEntity();
        // 对方邮箱地址
        mailEntity.setToAccount("手机号@163.com");
        mailEntity.setSubject("备份mysql");
        mailEntity.setContent("备份mysql的my_log数据库");
        File file = null;
        long thisTime = System.currentTimeMillis();
        // 这里是处理备份的sql文件是否写入完成,这里是10秒
        while (System.currentTimeMillis() - thisTime < 10*1000) {
            file = new File(filePath);
            if(file.exists() && file.isFile()) {
                break;
            } else {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        mailEntity.setAttachmentFile(file);
        MailUtils.sendMail(mailEntity);
        // 删除备份文件
        new Thread(new RemoveBackupSqlFileThread(filePath)).start();
        Map map = new HashMap();
        map.put("code", "0");
        map.put("msg", "已发送至邮箱");
        return map;
    }

    注:如果win备份mysql文件大小为0,那么可以考虑用new String[]{"cmd", "/c", shell}。参考下面Linux运行命令方法

    2、Linux下备份mysql并发送邮件

    配置my.cnf文件

    vi my.cnf打开文件【按i进入编辑状态,按Esc退出编辑,按:wq保存退出查看文件】

    [client]
    host=内网ip
    user=用户名
    password=密码

    springboot的配置,阿里云服务器封了25端口,要用465端口

     1 mail:
     2         default-encoding: UTF-8
     3         host: smtp.mxhichina.com      #阿里云发送服务器地址
     4 #            port: 25                      #端口号
     5         username: 邮箱地址        #发送人地址
     6         password: 密码   #密码
     7         properties:
     8               mail:
     9                 smtp:
    10                   starttls:
    11                     enable: true
    12                     required: true
    13                   auth: true
    14                   socketFactory:
    15                     class: javax.net.ssl.SSLSocketFactory
    16                     port: 465

    备份数据,发送邮件,删除备份文件

     1 @GetMapping("backup")
     2 @ResponseBody
     3 public Map backup(){
     4     String thisDateTime = DateUtils.getDateTime("yyyyMMdd_HHmmss");
     5     String filePath;
     6     String shell;
     7     // 通过获取系统名称是否包含windows来判断是win还是Linux
     8     if(System.getProperties().getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1) {
     9         filePath = "C:/temp/myLog_" + thisDateTime + ".sql";
    10         shell = ""D:/Program Files/MySQL/MySQL Server 5.7/bin/mysqldump.exe" --defaults-extra-file="D:/ProgramData/MySQL/MySQL Server 5.7/my.ini" -B my_log>" + filePath;
    11         shell = "cmd /c " + shell;
    12     } else {
    13         filePath = "/home/backup/myLog_" + thisDateTime + ".sql";
    14         shell = "/usr/local/mysql/bin/mysqldump --defaults-extra-file=/usr/local/mysql/my.cnf -B my_log>" + filePath;
    15     }
    16     Runtime runTime = Runtime.getRuntime();
    17     Map map = new HashMap();
    18     if (null != runTime) {
    19         try {
    20             if(System.getProperties().getProperty("os.name").toUpperCase().indexOf("WINDOWS") != -1) {
    21                 runTime.exec(shell);
    22             } else {
    23                 // linux运行shell命令要加
    24                 runTime.exec(new String[]{"/bin/sh", "-c", shell});
    25             }
    26         } catch (IOException e) {
    27             e.printStackTrace();
    28         }
    29         MailEntity mailEntity = new MailEntity();
    30         mailEntity.setToAccount("对方邮箱地址");
    31         mailEntity.setSubject("备份mysql");
    32         mailEntity.setContent("备份mysql的my_log数据库");
    33         File file = null;
    34         long thisTime = System.currentTimeMillis();
    35         while (System.currentTimeMillis() - thisTime < 10*1000) {
    36             file = new File(filePath);
    37             if(file.exists() && file.isFile()) {
    38                 break;
    39             } else {
    40                 try {
    41                     Thread.sleep(200);
    42                 } catch (InterruptedException e) {
    43                     e.printStackTrace();
    44                 }
    45             }
    46         }
    47         mailEntity.setAttachmentFile(file);
    48         MailUtils.sendMail(mailEntity);
    49         // 删除备份文件
    50         new Thread(new RemoveBackupSqlFileThread(filePath)).start();
    51         map.put("code", "0");
    52         map.put("msg", "已发送至邮箱");
    53     } else {
    54         map.put("code", "1");
    55         map.put("msg", "获取Runtime为null,不能运行命令");
    56     }
    57     return map;
    58 }

    后面测试定时备份数据和发送邮件

  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    微信小程序TodoList
    C语言88案例-找出数列中的最大值和最小值
    C语言88案例-使用指针的指针输出字符串
  • 原文地址:https://www.cnblogs.com/xiaostudy/p/11247015.html
Copyright © 2011-2022 走看看