首先加入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 }