From 5de223d5da38bcffa0ef74daebefece91d44f2fa Mon Sep 17 00:00:00 2001 From: tursom Date: Sat, 7 Mar 2020 17:30:36 +0800 Subject: [PATCH] add mail module --- settings.gradle | 1 + src/test/kotlin/main.kt | 12 +++ utils/mail/build.gradle | 7 ++ .../main/kotlin/cn/tursom/mail/EmailData.kt | 99 +++++++++++++++++++ .../kotlin/cn/tursom/mail/GroupEmailData.kt | 82 +++++++++++++++ .../kotlin/cn/tursom/mail/MailStructure.kt | 35 +++++++ .../cn/tursom/mail/MultipleEmailData.kt | 85 ++++++++++++++++ 7 files changed, 321 insertions(+) create mode 100644 src/test/kotlin/main.kt create mode 100644 utils/mail/build.gradle create mode 100644 utils/mail/src/main/kotlin/cn/tursom/mail/EmailData.kt create mode 100644 utils/mail/src/main/kotlin/cn/tursom/mail/GroupEmailData.kt create mode 100644 utils/mail/src/main/kotlin/cn/tursom/mail/MailStructure.kt create mode 100644 utils/mail/src/main/kotlin/cn/tursom/mail/MultipleEmailData.kt diff --git a/settings.gradle b/settings.gradle index ed6d245..862b3a4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -10,4 +10,5 @@ include 'microservices' include 'database:database-mysql' include 'database:mongodb' include 'utils:ws-client' +include 'utils:mail' diff --git a/src/test/kotlin/main.kt b/src/test/kotlin/main.kt new file mode 100644 index 0000000..cac13fb --- /dev/null +++ b/src/test/kotlin/main.kt @@ -0,0 +1,12 @@ +import java.math.BigInteger + +fun main() { + val two = BigInteger.valueOf(2) + val three = BigInteger.valueOf(3) + val ten = BigInteger.TEN + var i = BigInteger.ONE + repeat(1000) { + i *= two + print("${i / ten / ten / ten % ten}") + } +} \ No newline at end of file diff --git a/utils/mail/build.gradle b/utils/mail/build.gradle new file mode 100644 index 0000000..f013574 --- /dev/null +++ b/utils/mail/build.gradle @@ -0,0 +1,7 @@ +dependencies { + implementation project(":") + // https://mvnrepository.com/artifact/javax.mail/mail + //compile group: 'javax.mail', name: 'mail', version: '1.4' + // https://mvnrepository.com/artifact/com.sun.mail/javax.mail + compile group: 'com.sun.mail', name: 'javax.mail', version: '1.5.1' +} diff --git a/utils/mail/src/main/kotlin/cn/tursom/mail/EmailData.kt b/utils/mail/src/main/kotlin/cn/tursom/mail/EmailData.kt new file mode 100644 index 0000000..87b0206 --- /dev/null +++ b/utils/mail/src/main/kotlin/cn/tursom/mail/EmailData.kt @@ -0,0 +1,99 @@ +package cn.tursom.mail + +import cn.tursom.core.base64 +import com.sun.mail.util.MailSSLSocketFactory +import java.net.URL +import java.util.* +import javax.activation.DataHandler +import javax.activation.FileDataSource +import javax.mail.Address +import javax.mail.Session +import javax.mail.internet.InternetAddress +import javax.mail.internet.MimeBodyPart +import javax.mail.internet.MimeMessage +import javax.mail.internet.MimeMultipart + +/** + * 用于发送一个邮件的所有信息 + * + * @param host smtp服务器地址 + * @param port smtp服务器端口,默认465 + * @param name 邮箱用户名 + * @param password 邮箱密码 + * @param from 发送邮箱 + * @param to 目标邮箱 + * @param subject 邮件主题 + * @param html 邮件主题内容 + * @param text html为空时的邮件主题内容 + * @param image 图片 + * @param attachment 附件 + */ +data class EmailData( + var host: String?, var port: Int?, var name: String?, var password: String?, var from: String?, + var to: String?, var subject: String?, var html: String? = null, var text: String? = null, + var image: Map? = null, var attachment: List? = null +) { + /** + * 发送邮件 + */ + fun send() { + val props = Properties() +// props["mail.debug"] = "true" // 开启debug调试 + props["mail.smtp.auth"] = "true" // 发送服务器需要身份验证 + props["mail.smtp.host"] = host // 设置邮件服务器主机名 + props["mail.transport.protocol"] = "smtps" // 发送邮件协议名称 + props["mail.smtp.port"] = port + val sf = MailSSLSocketFactory() + sf.isTrustAllHosts = true + props["mail.smtp.ssl.enable"] = "true" + props["mail.smtp.ssl.socketFactory"] = sf + + val session = Session.getInstance(props) + //邮件内容部分 + val msg = MimeMessage(session) + val multipart = MimeMultipart() + // 添加文本 + if (html ?: "null" != "null") { + val htmlBodyPart = MimeBodyPart() + htmlBodyPart.setContent(html, "text/html;charset=UTF-8") + multipart.addBodyPart(htmlBodyPart) + } else { + val textPart = MimeBodyPart() + textPart.setText(text) + multipart.addBodyPart(textPart) + } + //添加图片 + image?.forEach { + //创建用于保存图片的MimeBodyPart对象,并将它保存到MimeMultipart中 + val gifBodyPart = MimeBodyPart() + if (it.value.startsWith("http://") or it.value.startsWith("https://")) { + gifBodyPart.dataHandler = DataHandler(URL(it.value)) + } else { + val fds = FileDataSource(it.value)//图片所在的目录的绝对路径 + gifBodyPart.dataHandler = DataHandler(fds) + } + gifBodyPart.contentID = it.key //cid的值 + multipart.addBodyPart(gifBodyPart) + } + //添加附件 + attachment?.forEach { fileName -> + val adjunct = MimeBodyPart() + val fileDataSource = FileDataSource(fileName) + adjunct.dataHandler = DataHandler(fileDataSource) +// adjunct.fileName = changeEncode(fileDataSource.name) + adjunct.fileName = fileDataSource.name.base64() + multipart.addBodyPart(adjunct) + } + msg.setContent(multipart) + //邮件主题 + msg.subject = subject + //邮件发送者 + msg.setFrom(InternetAddress(from)) + //发送邮件 + val transport = session.transport + transport.connect(host, name, password) + + transport.sendMessage(msg, arrayOf
(InternetAddress(to))) + transport.close() + } +} \ No newline at end of file diff --git a/utils/mail/src/main/kotlin/cn/tursom/mail/GroupEmailData.kt b/utils/mail/src/main/kotlin/cn/tursom/mail/GroupEmailData.kt new file mode 100644 index 0000000..f42a4ef --- /dev/null +++ b/utils/mail/src/main/kotlin/cn/tursom/mail/GroupEmailData.kt @@ -0,0 +1,82 @@ +package cn.tursom.mail + +import cn.tursom.core.base64 +import com.sun.mail.util.MailSSLSocketFactory +import java.net.URL +import java.util.* +import javax.activation.DataHandler +import javax.activation.FileDataSource +import javax.mail.Address +import javax.mail.Session +import javax.mail.internet.* + +/** + * 用于表示群发邮件的数据类 + * 拥有一个send函数,当运行在TreeDiagram服务器上时可以直接发送邮件 + */ +data class GroupEmailData( + var host: String?, var port: Int?, var name: String?, var password: String?, var from: String?, + var to: List?, var subject: String?, var html: String? = null, var text: String? = null, + var image: Map? = null, var attachment: List? = null +) { + fun send() { + val props = Properties() + // props["mail.debug"] = "true" // 开启debug调试 + props["mail.smtp.auth"] = "true" // 发送服务器需要身份验证 + props["mail.smtp.host"] = host // 设置邮件服务器主机名 + props["mail.transport.protocol"] = "smtps" // 发送邮件协议名称 + props["mail.smtp.port"] = port + val sf = MailSSLSocketFactory() + sf.isTrustAllHosts = true + props["mail.smtp.ssl.enable"] = "true" + props["mail.smtp.ssl.socketFactory"] = sf + + val session = Session.getInstance(props) + //邮件内容部分 + val msg = MimeMessage(session) + val multipart = MimeMultipart() + // 添加文本 + if (html ?: "null" != "null") { + val htmlBodyPart = MimeBodyPart() + htmlBodyPart.setContent(html, "text/html;charset=UTF-8") + multipart.addBodyPart(htmlBodyPart) + } else { + val textPart = MimeBodyPart() + textPart.setText(text) + multipart.addBodyPart(textPart) + } + //添加图片 + image?.forEach { + //创建用于保存图片的MimeBodyPart对象,并将它保存到MimeMultipart中 + val gifBodyPart = MimeBodyPart() + if (it.value.startsWith("http://") or it.value.startsWith("https://")) { + gifBodyPart.dataHandler = DataHandler(URL(it.value)) + } else { + val fds = FileDataSource(it.value)//图片所在的目录的绝对路径 + gifBodyPart.dataHandler = DataHandler(fds) + } + gifBodyPart.contentID = it.key //cid的值 + multipart.addBodyPart(gifBodyPart) + } + //添加附件 + attachment?.forEach { fileName -> + val adjunct = MimeBodyPart() + val fileDataSource = FileDataSource(fileName) + adjunct.dataHandler = DataHandler(fileDataSource) + adjunct.fileName = fileDataSource.name.base64() + multipart.addBodyPart(adjunct) + } + msg.setContent(multipart) + //邮件主题 + msg.subject = subject + //邮件发送者 + msg.setFrom(InternetAddress(from)) + //发送邮件 + val transport = session.transport + transport.connect(host, name, password) + to?.forEach { + transport.sendMessage(msg, arrayOf
(InternetAddress(it))) + } + transport.close() + } +} \ No newline at end of file diff --git a/utils/mail/src/main/kotlin/cn/tursom/mail/MailStructure.kt b/utils/mail/src/main/kotlin/cn/tursom/mail/MailStructure.kt new file mode 100644 index 0000000..5cfcfd4 --- /dev/null +++ b/utils/mail/src/main/kotlin/cn/tursom/mail/MailStructure.kt @@ -0,0 +1,35 @@ +package cn.tursom.mail + +import java.util.* + +data class MailStructure( + val to: String?, val subject: String?, val html: String?, val text: String? = null, + val image: Map? = null, val attachment: Array? = null +) { + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as MailStructure + + if (to != other.to) return false + if (subject != other.subject) return false + if (html != other.html) return false + if (text != other.text) return false + if (image != other.image) return false + if (!Arrays.equals(attachment, other.attachment)) return false + + return true + } + + override fun hashCode(): Int { + var result = to?.hashCode() ?: 0 + result = 31 * result + (subject?.hashCode() ?: 0) + result = 31 * result + (html?.hashCode() ?: 0) + result = 31 * result + (text?.hashCode() ?: 0) + result = 31 * result + (image?.hashCode() ?: 0) + result = 31 * result + (attachment?.let { Arrays.hashCode(it) } ?: 0) + return result + } +} \ No newline at end of file diff --git a/utils/mail/src/main/kotlin/cn/tursom/mail/MultipleEmailData.kt b/utils/mail/src/main/kotlin/cn/tursom/mail/MultipleEmailData.kt new file mode 100644 index 0000000..2f150dc --- /dev/null +++ b/utils/mail/src/main/kotlin/cn/tursom/mail/MultipleEmailData.kt @@ -0,0 +1,85 @@ +package cn.tursom.mail + +import cn.tursom.core.base64 +import com.sun.mail.util.MailSSLSocketFactory +import java.net.URL +import java.util.* +import javax.activation.DataHandler +import javax.activation.FileDataSource +import javax.mail.Address +import javax.mail.Session +import javax.mail.internet.InternetAddress +import javax.mail.internet.MimeBodyPart +import javax.mail.internet.MimeMessage +import javax.mail.internet.MimeMultipart + +data class MultipleEmailData( + var host: String?, + var port: Int?, + var name: String?, + var password: String?, + var from: String?, + var to: List? +) { + fun send() { + val props = Properties() +// props["mail.debug"] = "true" // 开启debug调试 + props["mail.smtp.auth"] = "true" // 发送服务器需要身份验证 + props["mail.smtp.host"] = host // 设置邮件服务器主机名 + props["mail.transport.protocol"] = "smtps" // 发送邮件协议名称 + props["mail.smtp.port"] = port + val sf = MailSSLSocketFactory() + sf.isTrustAllHosts = true + props["mail.smtp.ssl.enable"] = "true" + props["mail.smtp.ssl.socketFactory"] = sf + + + val session = Session.getInstance(props) + //发送邮件 + val transport = session.transport + transport.connect(host, name, password) + to?.forEach { structure -> + //邮件内容部分 + val msg = MimeMessage(session) + val multipart = MimeMultipart() + // 添加文本 + if (structure.html ?: "null" != "null") { + val htmlBodyPart = MimeBodyPart() + htmlBodyPart.setContent(structure.html, "text/html;charset=UTF-8") + multipart.addBodyPart(htmlBodyPart) + } else { + val textPart = MimeBodyPart() + textPart.setText(structure.text) + multipart.addBodyPart(textPart) + } + //添加图片 + structure.image?.forEach { + //创建用于保存图片的MimeBodyPart对象,并将它保存到MimeMultipart中 + val gifBodyPart = MimeBodyPart() + if (it.value.startsWith("http://") or it.value.startsWith("https://")) { + gifBodyPart.dataHandler = DataHandler(URL(it.value)) + } else { + val fds = FileDataSource(it.value)//图片所在的目录的绝对路径 + gifBodyPart.dataHandler = DataHandler(fds) + } + gifBodyPart.contentID = it.key //cid的值 + multipart.addBodyPart(gifBodyPart) + } + //添加附件 + structure.attachment?.forEach { fileName -> + val adjunct = MimeBodyPart() + val fileDataSource = FileDataSource(fileName) + adjunct.dataHandler = DataHandler(fileDataSource) + adjunct.fileName = fileDataSource.name.base64() + multipart.addBodyPart(adjunct) + } + msg.setContent(multipart) + //邮件主题 + msg.subject = structure.subject + //邮件发送者 + msg.setFrom(InternetAddress(from)) + transport.sendMessage(msg, arrayOf
(InternetAddress(structure.to))) + } + transport.close() + } +} \ No newline at end of file