2026/3/22 7:06:20
网站建设
项目流程
济南网站建设公司晟创未来,上海软件开发企业,深圳网站建设公司613,央企网站建设1. 准备工作#xff1a;获取QQ邮箱SMTP授权码
在开始编写Java代码之前#xff0c;我们需要先获取QQ邮箱的SMTP授权码。这个授权码相当于一个专用密码#xff0c;用于第三方应用通过SMTP协议登录你的QQ邮箱发送邮件。我刚开始接触这个功能时#xff0c;也踩过直接用QQ密码登…1. 准备工作获取QQ邮箱SMTP授权码在开始编写Java代码之前我们需要先获取QQ邮箱的SMTP授权码。这个授权码相当于一个专用密码用于第三方应用通过SMTP协议登录你的QQ邮箱发送邮件。我刚开始接触这个功能时也踩过直接用QQ密码登录的坑结果一直报错后来才发现必须使用独立的授权码。具体操作步骤如下登录你的QQ邮箱网页版点击右上角的设置按钮选择账户选项卡向下滚动找到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务部分点击开启按钮如果已经开启会显示已开启状态按照页面提示发送短信验证验证通过后会生成一个16位的授权码重要提示这个授权码只会显示一次务必立即复制保存。我当初就是没及时保存结果不得不重新生成导致之前的代码配置都要跟着改。建议保存在安全的地方比如密码管理器。2. 项目配置添加邮件发送依赖现在我们来配置Java项目。根据我的经验目前最常用的Java邮件库有两种选择JavaMail APIOracle官方提供的标准APIApache Commons Email对JavaMail的简化封装我个人更推荐使用JavaMail API因为它是标准实现功能更全面。下面是Maven项目的依赖配置dependency groupIdcom.sun.mail/groupId artifactIdjavax.mail/artifactId version1.6.2/version /dependency如果你使用Gradle可以这样添加implementation com.sun.mail:javax.mail:1.6.2对于Spring Boot项目可以直接使用Spring提供的starterdependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-mail/artifactId /dependency我曾经在一个老项目中使用过commons-email虽然API确实简单一些但在处理附件和HTML内容时遇到了不少限制最后还是换回了JavaMail。3. 基础实现发送纯文本邮件现在我们来编写最基本的邮件发送代码。先看一个完整的示例然后我会逐步解释关键部分import java.util.Properties; import javax.mail.*; import javax.mail.internet.*; public class QQMailSender { public static void sendTextEmail(String to, String subject, String content) throws MessagingException { // 1. 配置连接参数 Properties props new Properties(); props.put(mail.smtp.host, smtp.qq.com); props.put(mail.smtp.port, 587); props.put(mail.smtp.auth, true); props.put(mail.smtp.starttls.enable, true); // 使用TLS加密 // 2. 创建Session实例 Session session Session.getInstance(props, new Authenticator() { Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(你的QQ邮箱, 你的授权码); } }); // 3. 创建邮件消息 Message message new MimeMessage(session); message.setFrom(new InternetAddress(你的QQ邮箱)); message.setRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject(subject); message.setText(content); // 4. 发送邮件 Transport.send(message); } }关键点解析SMTP配置mail.smtp.hostQQ邮箱的SMTP服务器地址mail.smtp.port可以使用465(SSL)或587(TLS)端口mail.smtp.auth必须开启认证mail.smtp.starttls.enable启用TLS加密认证信息 使用Authenticator匿名类提供邮箱账号和授权码。这里有个常见坑点密码要填授权码而不是QQ密码邮件构建setFrom发件人地址必须与认证邮箱一致setRecipient收件人地址可以添加多个setText设置纯文本内容测试代码public static void main(String[] args) { try { QQMailSender.sendTextEmail( recipientexample.com, 测试邮件主题, 这是一封测试邮件内容 ); System.out.println(邮件发送成功); } catch (MessagingException e) { System.err.println(邮件发送失败: e.getMessage()); } }4. 进阶功能发送HTML格式邮件在实际项目中我们通常需要发送更丰富的HTML格式邮件。下面是如何修改代码来支持HTMLpublic static void sendHtmlEmail(String to, String subject, String htmlContent) throws MessagingException { // ... 前面的配置代码与纯文本邮件相同 ... Message message new MimeMessage(session); message.setFrom(new InternetAddress(你的QQ邮箱)); message.setRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject(subject); // 设置HTML内容 message.setContent(htmlContent, text/html;charsetUTF-8); Transport.send(message); }HTML内容示例String html html body h1 stylecolor:red重要通知/h1 p尊敬的客户/p p您的验证码是strong123456/strong/p p请在10分钟内使用/p /body /html; sendHtmlEmail(userexample.com, 验证码通知, html);实用技巧可以使用Thymeleaf或FreeMarker模板引擎生成HTML内容内联CSS比外部CSS更可靠因为某些邮箱客户端会屏蔽外部样式避免使用复杂的JavaScript大多数邮箱会禁用脚本执行5. 添加附件功能实现发送带附件的邮件稍微复杂一些需要使用MimeMultipart和MimeBodyPartpublic static void sendEmailWithAttachment(String to, String subject, String content, File attachment) throws MessagingException, IOException { // ... 配置代码与之前相同 ... Message message new MimeMessage(session); message.setFrom(new InternetAddress(你的QQ邮箱)); message.setRecipient(Message.RecipientType.TO, new InternetAddress(to)); message.setSubject(subject); // 创建多部分消息 Multipart multipart new MimeMultipart(); // 文本部分 BodyPart messageBodyPart new MimeBodyPart(); messageBodyPart.setText(content); multipart.addBodyPart(messageBodyPart); // 附件部分 messageBodyPart new MimeBodyPart(); DataSource source new FileDataSource(attachment); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(attachment.getName()); multipart.addBodyPart(messageBodyPart); // 设置完整消息 message.setContent(multipart); Transport.send(message); }使用示例File file new File(report.pdf); sendEmailWithAttachment( clientexample.com, 月度报告, 请查收附件中的月度报告, file );注意事项附件大小限制QQ邮箱单封邮件总大小不超过50MB文件类型某些类型可能被邮箱服务器拦截如.exe文件中文文件名建议使用MimeUtility.encodeText处理中文文件名6. 实用技巧与常见问题解决在实际使用中我积累了一些实用技巧和问题解决方案1. 发送给多个收件人// 替换单个收件人的设置 InternetAddress[] addresses { new InternetAddress(user1example.com), new InternetAddress(user2example.com) }; message.setRecipients(Message.RecipientType.TO, addresses);2. 抄送和密送// 抄送 message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(cc1example.com,cc2example.com)); // 密送 message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(bccexample.com));3. 常见错误及解决535错误认证失败检查是否使用了授权码而非QQ密码确认邮箱账号是否正确完整地址如123456qq.comCould not connect to SMTP host检查网络连接尝试切换端口465/587确认防火墙未阻止出站连接554 DT:SPM被识别为垃圾邮件优化邮件内容减少敏感词添加退订链接控制发送频率4. 性能优化// 复用Session对象 private static final Session session Session.getInstance(props, authenticator); // 使用连接池Spring框架 Bean public JavaMailSender mailSender() { JavaMailSenderImpl sender new JavaMailSenderImpl(); sender.setHost(smtp.qq.com); sender.setPort(587); sender.setUsername(你的QQ邮箱); sender.setPassword(你的授权码); Properties props sender.getJavaMailProperties(); props.put(mail.transport.protocol, smtp); props.put(mail.smtp.auth, true); props.put(mail.smtp.starttls.enable, true); props.put(mail.debug, true); // 调试模式 return sender; }7. 完整工具类封装最后我将分享一个经过实战检验的邮件工具类包含以上所有功能import javax.mail.*; import javax.mail.internet.*; import javax.activation.*; import java.util.*; import java.io.*; public class EmailUtil { private static final String SMTP_HOST smtp.qq.com; private static final int SMTP_PORT 587; private static final String USERNAME 你的QQ邮箱; private static final String PASSWORD 你的授权码; private static Session getSession() { Properties props new Properties(); props.put(mail.smtp.host, SMTP_HOST); props.put(mail.smtp.port, SMTP_PORT); props.put(mail.smtp.auth, true); props.put(mail.smtp.starttls.enable, true); return Session.getInstance(props, new Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(USERNAME, PASSWORD); } }); } public static void sendTextEmail(String to, String subject, String text) throws MessagingException { sendEmail(to, subject, text, false, null); } public static void sendHtmlEmail(String to, String subject, String html) throws MessagingException { sendEmail(to, subject, html, true, null); } public static void sendEmailWithAttachment(String to, String subject, String text, File attachment) throws MessagingException, IOException { sendEmail(to, subject, text, false, new File[]{attachment}); } private static void sendEmail(String to, String subject, String content, boolean isHtml, File[] attachments) throws MessagingException { Message message new MimeMessage(getSession()); message.setFrom(new InternetAddress(USERNAME)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); message.setSubject(subject); if (attachments null || attachments.length 0) { // 无附件 message.setContent(content, isHtml ? text/html;charsetUTF-8 : text/plain); } else { // 有附件 Multipart multipart new MimeMultipart(); // 正文部分 MimeBodyPart textPart new MimeBodyPart(); textPart.setContent(content, isHtml ? text/html;charsetUTF-8 : text/plain); multipart.addBodyPart(textPart); // 附件部分 for (File file : attachments) { MimeBodyPart attachmentPart new MimeBodyPart(); attachmentPart.setDataHandler(new DataHandler(new FileDataSource(file))); attachmentPart.setFileName(MimeUtility.encodeText(file.getName())); multipart.addBodyPart(attachmentPart); } message.setContent(multipart); } Transport.send(message); } }这个工具类已经在我们公司的多个项目中稳定运行每天处理上千封邮件。使用时只需要根据需求调用对应的简化方法即可。对于更复杂的场景比如需要内嵌图片的HTML邮件可以进一步扩展这个工具类。