Java邮箱集成发送, 本文介绍了基于JavaMailSenderImpl和velocity模板引擎,发送自定义的邮件内容。
一、依赖引入
<dependency>
<groupId>com.crygier</groupId>
<artifactId>SpringUtils</artifactId>
<version>1.0.1</version>
<scope>compile</scope>
</dependency>
<!--邮件服务-->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.crygier</groupId>
<artifactId>SpringUtils</artifactId>
<version>1.0.1</version>
<scope>compile</scope>
</dependency>
二、邮箱发送工具类(javaMailSenderImpl)
SysEmailServiceProvider.java
@Component
@Scope(value = "singleton")
public class SysEmailServiceProvider {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private IFactoryEmailManageService factoryEmailManageService;
/**
* 系统邮箱发送服务实例,单例模式下使用到时再去加载
*/
private volatile JavaMailSenderImpl javaMailSender;
/**
* 双重检测机制懒汉式单例模式,防止多线程下多次实例化对象
*
* @return
*/
public JavaMailSenderImpl getJavaMailSender() {
if (javaMailSender == null) {
// 在代码块上加锁,比直接在方法上加锁效率高,因为锁的范围小了
synchronized (SysEmailServiceProvider.class) {
if (javaMailSender == null) {
// 从数据库查询邮件发送服务器配置
FactoryEmailManage sysEmail = factoryEmailManageService.selectFactoryEmailManageById(1L);
// 实例化对象
javaMailSender = buildJavaMailSenderBySysEmail(sysEmail);
}
}
}
return javaMailSender;
}
/**
* 清除当前的邮件发送对象(一般用于修改系统邮箱发送服务时)
*/
public void clearJavaMailSender() {
// 直接赋值为null,用的时候再实例化
javaMailSender = null;
}
/**
* 根据邮件服务配置对象生成邮件发送实例对象
*
* @param email
* @return
*/
public JavaMailSenderImpl buildJavaMailSenderBySysEmail(FactoryEmailManage email) {
if (email == null) {
logger.warn("邮件发送服务配置为null,无法实例化对象");
return null;
}
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
try {
javaMailSender.setHost(email.getEmailHost());
javaMailSender.setUsername(email.getEmailName());
javaMailSender.setPassword(RsaUtils.decryptByPrivateKey(email.getEmailPassword()));
javaMailSender.setPort(email.getEmailPort());
javaMailSender.setProtocol(email.getEmailProtocol());
javaMailSender.setDefaultEncoding("utf-8");
} catch (Exception e) {
logger.error("实例化邮件发送对象失败,失败原因:{}", e.getMessage());
}
return javaMailSender;
}
/**
* 邮件接收服务实例对象(不涉及多线程调用)
*/
private Store store;
/**
* 简单懒汉式单例模式,因为这个对象不涉及到多线程调用
*
* @return
*/
public Store getStore() throws Exception {
if (store == null) {
// 从数据库查询邮件发送服务器配置
FactoryEmailManage sysEmail = factoryEmailManageService.selectFactoryEmailManageById((long) 1);
store = buildStoreBySysEmail(sysEmail);
}
return store;
}
/**
* 清除当前的邮件接收对象(一般用于修改系统邮箱接收服务时)
*/
public void clearStore() {
// 直接赋值为null,用的时候再实例化
store = null;
}
/**
* 根据邮件服务配置对象生成邮件接收实例对象
*
* @param email
* @return
*/
public Store buildStoreBySysEmail(FactoryEmailManage email) throws Exception {
if (email == null) {
logger.warn("邮件接收服务配置为null,无法实例化对象");
return null;
}
Properties props = System.getProperties();
if ("pop3s".equals(email.getEmailProtocol())) {
props.setProperty("mail.pop3s.host", email.getEmailHost());
props.setProperty("mail.pop3s.port", email.getEmailPort().toString());
props.setProperty("mail.pop3s.auth", "true");
props.setProperty("mail.pop3s.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.pop3s.ssl.trust", "*");
} else if ("pop3".equals(email.getEmailProtocol())) {
props.setProperty("mail.pop3.host", email.getEmailHost());
props.setProperty("mail.pop3.port", email.getEmailPort().toString());
} else {
throw new Exception("邮件接收服务器暂不支持pop3以及pop3s之外的协议");
}
Session session = Session.getDefaultInstance(props, null);
Store store = null;
try {
store = session.getStore(email.getEmailProtocol());
} catch (NoSuchProviderException e) {
logger.error(e.getMessage(), e);
throw new Exception(e.getMessage());
} finally {
return store;
}
}
}
三、邮箱发送工具类(自定义内容)
样式调整、发件人、收件人、内容、主题等自定义设置,本文加上了图片和模板内容。
@Component
public class EmailSendUtils {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private IFactoryEmailManageService factoryEmailManageService;
@Autowired
private SysEmailServiceProvider sysEmailServiceProvider;
public void sendEmailAssignManage(Map<String, Object> addresseeMap, String content) throws Exception {
try {
JavaMailSenderImpl javaMailSender = sysEmailServiceProvider.getJavaMailSender();
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
mimeMessageHelper.setFrom(javaMailSender.getUsername());
if(addresseeMap.get("toReceiverGroup")!=null){ //收件人设置
mimeMessageHelper.setTo((String[]) addresseeMap.get("toReceiverGroup"));
}else if(addresseeMap.get("toReceiver")!=null){
mimeMessageHelper.setTo(new String[]{addresseeMap.get("toReceiver").toString()});
}
//邮件主题
mimeMessageHelper.setSubject(addresseeMap.get("emailSubject").toString());
//邮件内容
mimeMessageHelper.setText(content, true);
//邮件内容-图片
if(addresseeMap.get("logopng")!=null){
mimeMessageHelper.addInline("logo", (ClassPathResource)addresseeMap.get("logopng"));
}
if(addresseeMap.get("topbackground")!=null){
mimeMessageHelper.addInline("topbackground", (ClassPathResource)addresseeMap.get("topbackground"));
}
javaMailSender.send(mimeMessage);
} catch (MailAuthenticationException e) {
logger.error(e.getMessage(), e);
logger.error("邮箱用户名或密码不正确");
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.error("发送邮件失败,请检查邮箱配置");
}
}
}
四、邮箱发送
1、velocity模板内容设置
SimpleDateFormat formatterDay = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
StringWriter sw = new StringWriter();
VelocityContext context = new VelocityContext();
/内容设置
context.put("warningType", "一次直通率预警");
context.put("caId", "S01");
context.put("content", factoryWarning.getContent());
context.put("responsibility", "责任人name");
context.put("happenTime", formatterDay.format(factoryWarning.getHappenTime()));
context.put("currentTime", formatterDay.format(new Date()));
Template template = Velocity.getTemplate("vm/warningSingleEmail.vm");
template.merge(context, sw);
String mailText = sw.toString();
2、velocity模板
warningSingleEmail.vm
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body style="font-size: 14px ;width: 100%;height: 100%;">
<div style="background: #EEE;width: 90%; height: 100%;margin:0px auto;">
<div style="max-width: 680px;width: 680px;margin:0px auto;">
<table align="center" border="0" cellpadding="0" cellspacing="0"
style='background: rgb(255, 255, 255); width: 680px; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; border: none; border-collapse: collapse; max-width: 680px; margin: 0; auto; empty-cells: show;'>
<tbody>
<tr style="user-select: none;">
<td align="center"
style="width: 680px; padding: 0px; text-align: center; min-width: 5px; user-select: text;">
<img
alt="top-background" width="680"
src="cid:topbackground"
style="width: 680px; max-width: 100%;height: 150px; cursor: pointer;"
>
## <p style="position: absolute;left: 35%; top: 1%;color: white; font-size: 3rem; font-weight:bolder; font-family: fantasy">预警系统提醒</p>
</tr>
</tbody>
</table>
<table align="center" border="0" cellpadding="0" cellspacing="0"
style='background: rgb(239, 249, 254); width: 680px; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; border: none; border-collapse: collapse; max-width: 680px; margin: 0px; empty-cells: show;'>
<tbody>
<tr style="background: rgb(239, 249, 254); user-select: none;">
<td style="background: rgb(239, 249, 254); width: 40px; color: rgb(160, 160, 160); line-height: 1.6; padding: 10px 0px; font-size: 14px; min-width: 5px; user-select: text;">
</td>
<td style="background: rgb(239, 249, 254); max-width: 600px;height: 500px; width: 600px; color: rgb(160, 160, 160); line-height: 1.6; padding: 10px 0px; font-size: 14px; min-width: 5px; user-select: text; text-align: left;">
<p style="text-align: left;"><span style="color: rgb(71, 85, 119);">尊敬的用户:</span></p>
<p><span style="color: rgb(71, 85, 119);"> 您有新的${warningType}产生,请及时处理!</span>
</p>
<p><span style="color: rgb(71, 85, 119);"><br></span></p>
<p><span style="color: rgb(71, 85, 119);">以下为本次预警的主要信息:</span></p>
<p><span style="color: rgb(71, 85, 119);"><b>预警类别:</b>${warningType}</span></p>
#if(${caId})
<p><span style="color: rgb(71, 85, 119);"><b>线别:</b>${caId}</span></p>
#end
<p><span style="color: rgb(71, 85, 119);"><b>描述:</b>${content}</span></p>
<p><span style="color: rgb(71, 85, 119);"><b>责任人:</b>${responsibility}</span></p>
<p><span style="color: rgb(71, 85, 119);"><b>发生时间:</b>${happenTime}</span></p>
<div style="float: right;font-size: 16px;font-weight: bold;margin-top: 20px">${currentTime}</div>
</td>
<td style="background: rgb(239, 249, 254); width: 40px; color: rgb(160, 160, 160); line-height: 1.6; padding: 10px 0px; font-size: 14px; min-width: 5px; user-select: text;">
<br></td>
</tr>
</tbody>
</table>
<table align="center" border="0" cellpadding="0" cellspacing="0"
style='background: rgb(255, 255, 255); width: 680px; height: 150px;font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif; border: none; border-collapse: collapse; max-width: 680px; margin: 0px auto; empty-cells: show;'>
<tbody>
<tr style="user-select: none;">
<td align="center"
style="width: 680px; padding: 0px; text-align: center; min-width: 5px; height: 150px; user-select: text;">
<img
alt="lbs-foot" width="680"
src="cid:logo"
style="width: 680px; max-width: 40%; min-height: 50%;cursor: pointer;"
/>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
3、收发件人和主题等设置
Map<String, Object> content = new HashMap<>();
//设置收件人邮箱
// content.put("toReceiver", "**@163.com");
//设置收件人邮箱-多人群组
String receiversEmail[] = ["**@163.com","**@126.com"];
content.put("toReceiverGroup", receiversEmail);
//设置邮件主题
content.put("emailSubject", "预警系统:您有新的预警产生!");
ClassPathResource logoPng = new ClassPathResource("vm/warning-logo.png");//从本地文件夹中获取所需图片
content.put("logopng",logoPng);
ClassPathResource topbackground = new ClassPathResource("vm/warning-top.png");//从本地文件夹中获取所需图片
content.put("topbackground",topbackground);
4、发送邮件调用
//发送邮件
emailSendUtils.sendEmailAssignManage(content, mailText);