Springboot邮件发送思路分析
毕业设计里需要邮件发送,所以学习,总的来讲,我考虑以下几点,
- 代码量少,代码简单.配置少,一看就懂,使用 JavaMail 太麻烦了.
- 异步执行,添加员工之后会发送入职邮件,
- 多线程处理,设计里有一个公告推送的功能,就是发布一个公告会给所以员工发一份公告内容的邮件.
方法一:之前电脑里装了Python环境,所以最开始用Python脚本的方式实现,主要是觉得Python太精干了,在Service里调用执行Python脚本.需要的参数以命令行的方式传参,线程池使用
ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>();
- 这样的考虑是因为Runtime.getRuntime().exec()来调用脚本,他会生成一个新的进程去运行调用的程序。不在当前进程中,是异步执行,不调用waitFor()方法.
- 脚本的话,后来修改好修改,不会影响生产部署.
- 这样做了一下,单邮件发送确实OK,方便,简单.但是多线程处理的话,cup就爆了,而且不同的系统编码格式,路径表示不同,在开发环境OK(Win10),在生产环境(Linux)不行,
- 后来查发现,在java中,调用runtime线程执行脚本是非常消耗资源的,不建议频繁使用!,而且需要考虑阻塞问题.如果发送多条的话很麻烦.所以这种方法放弃.
python脚本格式:
import smtplib from email.mime.text import MIMEText from email.header import Header # 第三方 SMTP 服务 mail_host = "smtp.163.com" # 设置服务器 mail_user = "AAAAAA@163.com" # 发邮件的账户名 mail_pass = "******" # 授权码 sender = 'AAAAAA@163.com' receivers = ['BBBBBB@qq.com'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 # 三个参数:第一个为文本内容,第二个设置格式,plain:文本,html:HTML格式,第三个 utf-8 设置编码 message = MIMEText('本次邮件的内容', 'plain', 'utf-8') message['From'] = Header("AAAAAA@163.com") # 邮件中的发件人 message['To'] = Header("BBBBBB@qq.com") # 邮件中的收件人 subject = '邮件主题' message['Subject'] = Header(subject, 'utf-8') try: smtpObj = smtplib.SMTP() smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号 smtpObj.login(mail_user, mail_pass) # 发件人邮箱账号、收件人邮箱账号、发送邮件 smtpObj.sendmail(sender, receivers, message.as_string()) print("邮件发送成功") except smtplib.SMTPException: print("Error: 无法发送邮件")
以命令行的方式发送,类比在cmd里执行 Python 文件地址 要传递的参数的格式 ,这里要注意参数有大小有限制.
Java代码
final static Logger logger = LoggerFactory.getLogger(EmailUtils.class); final static String PATH = "src\\main\\java\\com\\liruilong\\hros\\script\\"; public static void sendEmail(EmailModel emailModel) { String emailTo = emailModel.getEmployee().getEmail(); String username = emailModel.getEmployee().getName(); String titles = emailModel.getTitle(); String pathPy = PATH + emailModel.getPath();
//命令行输入的字符串, [python, src\main\java\com\liruilong\hros\script\sendemailpy.py, 1224973008@qq.com, 测试, 12312, <p>123123</p>] String[] args = new String[]{"python", pathPy, emailTo, username, titles}; logger.info(Arrays.toString(args)); try { Process process = Runtime.getRuntime().exec(args); } catch (IOException e) { e.printStackTrace(); } }
Python代码:使用sys模块的 sys.argv[]传递参数,
格式为: 文件地址 参数1 参数2 ....
命令行参数:[ src\main\java\com\liruilong\hros\script\sendemailpy.py, 1224973008@qq.com, 测试, 12312, <p>123123</p>]
# smtplib 用于邮件的发信动作 import smtplib import sys from email.mime.text import MIMEText # email 用于构建邮件内容 from email.header import Header # 用于构建邮件头 # 发信方的信息:发信邮箱,QQ 邮箱授权码 from_addr = 'liruilong108@foxmail.com' password = 'xznjnyvgnvmuicji' # 收信方邮箱, to_addr = sys.argv[1] #to_addr ='1224965096@qq.com' # 发信服务器 smtp_server = 'smtp.qq.com' # 邮箱正文内容,第一个参数为内容,第二个参数为格式(plain 为纯文本),第三个参数为编码 msg = MIMEText( '<p class="ql-align-justify"><strong>尊敬的<u> '+ sys.argv[2]+' </u>女士/先生:</strong></p><p class="ql-align-justify"> 感谢并欢迎您加入XXXX有限公司这支优秀的团队,成为我们亲密的工作伙伴!</p>' , 'HTML', 'utf-8') # 邮件头信息 msg['From'] = Header(from_addr) msg['To'] = Header(to_addr) #邮件titl msg['Subject'] = Header(sys.argv[3]) # 开启发信服务,这里使用的是加密传输 server = smtplib.SMTP_SSL() server.connect(smtp_server, 465) # 登录发信邮箱 server.login(from_addr, password) # 发送邮件 server.sendmail(from_addr, to_addr, msg.as_string()) # 关闭服务器 server.quit()
方法二,使用springboot集成的邮件发送依赖,spring-boot-starter-mail, 使用MailSenderAutoConfiguration 和自带线程池注解的方法:
- 后来发现直接使用spring-boot-starter-mail,的依赖包也挺方便,需要配置的不是太多.
这个有时间整理
RunTime.getRuntime().exec()运行脚本命令介绍和阻塞:
用法: public Process exec(String command)-----在单独的进程中执行指定的字符串命令。
在windows下相当于直接调用 /开始/搜索程序和文件 的指令,比如
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构