package com.yonyou.threatIntelligence.service.impl;
import com.sun.mail.util.MailSSLSocketFactory;
import com.yonyou.threatIntelligence.dao.EmailDOMapper;
import com.yonyou.threatIntelligence.entity.Email;
import com.yonyou.threatIntelligence.service.SendEmailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.GeneralSecurityException;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
@Slf4j
@Service
public class SendEmailServiceImpl implements SendEmailService {
/**
* smtp邮件服务器 smtp.qq.com
*/
@Value("${email.host}")
private String emailHost;
/**
* 邮件发送协议 smtp
*/
@Value("${email.protocol}")
private String emailProtocol;
/**
* 是否需要身份认证
*/
@Value("${smtp.auth}")
private String smtpAuth;
@Value("${email}")
private String email;
@Value("${authorization.code}")
private String authorizationCode;
@Resource
private EmailDOMapper emailDOMapper;
/**
* 发送邮件
*/
@Override
public void sendEmail() throws GeneralSecurityException {
// 设置邮件发送基本属性
// 获取系统属性
Properties prop = new Properties();
// 设置smtp服务器主机
prop.setProperty("mail.host", emailHost);
// 设置邮件发送协议
prop.setProperty("mail.transport.protocol", emailProtocol);
// 设置是否需要身份认证
prop.setProperty("mail.smtp.auth", smtpAuth);
// 关于QQ邮箱,还要设置SSL加密,加上以下代码即可
MailSSLSocketFactory sf = new MailSSLSocketFactory();
sf.setTrustAllHosts(true);
prop.put("mail.smtp.ssl.enable", "true");
prop.put("mail.smtp.ssl.socketFactory", sf);
// 创建session实例对象
Session session = Session.getInstance(prop, new Authenticator() {
public PasswordAuthentication getPasswordAuthentication() {
//发件人邮件用户名、授权码
return new PasswordAuthentication(email, authorizationCode);
}
});
// 启用调试模式,这样就可以查看到程序发送email的运行状态
session.setDebug(true);
try{
// 获取transport实例对象
Transport ts = session.getTransport("smtp");
// 打开连接
// ts.connect(email, authorizationCode);
ts.connect();
// 创建消息
Message message = createEmail(session);
ts.sendMessage(message, message.getAllRecipients());
// ts.close();
} catch (MessagingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建邮件:设置发件人、收件人、邮件信息
* @param session
* @return
* @throws Exception
*/
@Override
public Message createEmail(Session session) throws Exception{
MimeMessage message = new MimeMessage(session);
// 发件人
message.setFrom(new InternetAddress(email));
// 从数据库中获取邮箱
// TODO:获取订阅特定主题的网络威胁信息的用户邮箱
List<String> emails = selectEmail();
InternetAddress[] sendTo = new InternetAddress[emails.size()];
for(int i = 0; i < emails.size(); i++){
log.info("发送到用户:" + emails.get(i));
sendTo[i] = new InternetAddress(emails.get(i));
}
// 设置收信人
// TO:收件人、CC:抄送、BCC:密送
message.setRecipients(Message.RecipientType.TO, sendTo);
// 设置标题
message.setSubject("网络威胁信息测试标题");
// 设置邮件内容
// TODO:从数据库中获取要发送的网络威胁相关信息
String info = "网络威胁相关测试信息";
message.setContent(info, "text/html;charset=UTF-8");
message.saveChanges();
return message;
}
/**
* 从数据库中查询邮箱
* @return
*/
@Override
public List<String> selectEmail(){
List<Email> emails = emailDOMapper.listEmails();
List<String> list = emails.stream().map(email -> {
return email.getEmail();
}).collect(Collectors.toList());
return list;
}
}
需要注意的几点:
1) 类中的一些常量在application.properties中配置
2) QQ邮箱授权码的获取方式
QQ邮箱帮助中心之授权码的获取方式。只需要把POP3/SMTP服务开启即可。