在日常中遇到了需要实现一个发送邮件的需求,完成之后记录下实现方法及自己遇到的一些问题及解决办法。
常用SMTP服务相关地址及端口
一、通过javax.mail实现发送邮件
1.引入相关坐标
<!-- 发送邮件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.8</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
2.创建发送邮件工具类,以outlook为例子。(其中固定参数可以抽取出来放到配置文件中)
/**
* @param subject 标题
* @param mailText 邮件内容
* @param addressListTO 收件人
* @param addressListCc CC收件人
* @param fileFlg 0:存在附件,1:无附件
* @param filePath 附件路径
* */
public boolean sendRawMail(final String subject,
String mailText,
String addressListTO,
String addressListCc,
String addressListBcc,
String fileFlg,
String filePath) {
// 属性设定
Properties properties = System.getProperties();
// 服务地址
properties.put("mail.smtp.host", "smtp.office365.com");
// 认证
properties.put("mail.smtp.auth", "true");
// 服务端口
properties.put("mail.smtp.port", 587);
// STARTTLS
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.debug", "true");
// 超时
properties.put("mail.smtp.connectiontimeout", "10000");
properties.put("mail.smtp.timeout", "10000");
//发件人设置
String userId = "****";//发件人用户名
String password = "****";//发件人密码(无需使用授权码,有些邮箱会需要授权码来验证,如163.com等,可根据需要自行验证)
String mailAddress = "****";//发件人邮箱地址
try {
//创建会话
final String finalUserId = userId;
final String finalPassword = password;
Session session = Session.getInstance(properties , new Authenticator(){
@Override
protected PasswordAuthentication getPasswordAuthentication(){
//密码认证
return new PasswordAuthentication(finalUserId, finalPassword);
}
});
final Message message = new MimeMessage(session);
// 收件人基本信息
message.setFrom(new InternetAddress(mailAddress));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(addressListTO, false));
message.setRecipients(Message.RecipientType.CC, InternetAddress.parse(addressListCc, false));
message.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(addressListBcc, false));
// 邮件标题
message.setSubject(subject);
message.setHeader("Content-Type", "text/html; charset=iso-2022-jp");
//是否存在附件
if("1".equals(fileFlg)) {
final MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(mailText, "text/html; charset=utf-8");
final MimeMultipart multipart = new MimeMultipart();
final MimeBodyPart attPart = new MimeBodyPart();
FileDataSource fileDataSource = new FileDataSource(filePath);
attPart.setDataHandler(new DataHandler(fileDataSource));
attPart.setFileName(MimeUtility.encodeWord(fileDataSource.getName()));
multipart.addBodyPart(attPart);
multipart.addBodyPart(textPart);
message.setContent(multipart);
} else {
message.setContent(mailText,"text/html; charset=iso-2022-jp");
}
// 发送邮件
Transport.send(message);
System.out.println("发送成功");
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
发送邮件功能代码部分以上所示
二、我遇到的问题
在执行过程中,出现了 javax.mail.MessagingException: Could not convert socket to TLS 异常信息(如下图),排查代码过后未发现有何异常。
翻译内容是没有合适的协议。百度了下发现好多人遇到过此问题。适用本次代码问题原因是JDK版本原因,解决方案如下:
更改JDK配置文件
/jre/lib/security/java.security
删除 SSLv3, TLSv1, TLSv1.1