465端口和587端口差异对比可参考:https://liaoxuefeng.com/books/java/spring/integration/javamail/index.html
特别注意写在最前面:
1.SMTP邮箱服务 有两个端口SMTP 端口号(SSL)465 SMTP 端口号(starttls)587所以,在发送邮件时,一定要注意 不同端口,配置Properties细节处的差异。 细节不正确,会导致 ① null指针异常 ② Transport.send(message)后线程卡死无响应以下代码,就是以 465端口发送邮件的完整代码,特别注意标红部分。2.properties.put("mail.transport.protocol", "smtp"); 配置未指定,会导致 null指针异常java.lang.NullPointerException: nullat com.sun.mail.handlers.text_plain.writeTo(text_plain.java:133)at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:889)at javax.activation.DataHandler.writeTo(DataHandler.java:317)at javax.mail.internet.MimeUtility.getEncoding(MimeUtility.java:340)at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1573)at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1172)at javax.mail.internet.MimeMultipart.updateHeaders(MimeMultipart.java:522)at javax.mail.internet.MimeBodyPart.updateHeaders(MimeBodyPart.java:1531)at javax.mail.internet.MimeMessage.updateHeaders(MimeMessage.java:2271)at javax.mail.internet.MimeMessage.saveChanges(MimeMessage.java:2231)3.properties.put("mail.smtp.ssl.enable", "false");properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 配置未指定,会导致 Transport.send(message); 执行后无响应,线程挂起
util核心代码:
import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j;import javax.activation.DataHandler; import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.*; import javax.mail.internet.*; import java.io.File; import java.util.Properties;@Slf4j public class MailUtils {public static void sendMail() {// 邮件服务器配置String host = "smtp.XXX.cn"; // 邮件服务器地址String port = "465"; // 邮件服务器端口号String username = "marketingdata-noreply@XX.com"; // 发件人邮箱String password = "OLiafELfknqYtQ6x"; // 发件人邮箱密码// 邮件内容String to = "angel.sxd@XXX.com"; // 收件人邮箱String subject = "暂占邮件标题坑位之看我几分像从前";String body = "这是一封测试邮件,包含附件。";String attachmentPath = "/暂占邮件标题坑位之看我几分像从前.xlsx"; // 附件路径 Properties properties = new Properties();properties.put("mail.transport.protocol", "smtp");properties.put("mail.smtp.host", host);properties.put("mail.smtp.socketFactory.port", port);properties.put("mail.smtp.auth", "true");properties.put("mail.smtp.starttls.enable", "true");properties.put("mail.smtp.ssl.enable", "false");properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");Session session = Session.getInstance(properties, new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication(username, password);}});session.setDebug(true);log.info("send mail info begin1 props:{} session:{}", JSON.toJSONString(properties), cn.hutool.json.JSONUtil.toJsonStr(session));try {// 创建邮件消息MimeMessage message = new MimeMessage(session);message.setFrom(new InternetAddress(username));message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));message.setSubject(subject);// 创建邮件正文MimeBodyPart textPart = new MimeBodyPart();textPart.setText(body);// 创建附件MimeBodyPart attachmentPart = new MimeBodyPart();File attachmentFile = new File(attachmentPath);DataSource source = new FileDataSource(attachmentFile);attachmentPart.setDataHandler(new DataHandler(source));attachmentPart.setFileName(attachmentFile.getName());// 组合正文和附件Multipart multipart = new MimeMultipart();multipart.addBodyPart(textPart);multipart.addBodyPart(attachmentPart);message.setContent(multipart);log.info("send mail info begin2 message:{} ", cn.hutool.json.JSONUtil.toJsonStr(message));// 发送邮件 Transport.send(message);log.info("send mail info end message:{} ", cn.hutool.json.JSONUtil.toJsonStr(message));} catch (AddressException e) {throw new RuntimeException(e);} catch (MessagingException e) {throw new RuntimeException(e);}}}
邮件发送成功如图: