• 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 }

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

  • 相关阅读:
    C#拼音转换,将简体中文转换成拼音
    C#发送邮件
    textBox只能输入汉字
    IOS中UIScrollView的详细使用
    AngularJs学习教程
    IOS-简单计时器的使用
    IOS-多视图控制器之间的切换
    IOS播放音乐和音效
    Nodejs_day04
    Nodejs_day03
  • 原文地址:https://www.cnblogs.com/xiaostudy/p/11247015.html
Copyright © 2020-2023  润新知