化工企业常用推广网站,wordpress数据库改密码忘记,湘潭网站seo,电梯网站建设最近做了一个发送邮件的功能#xff0c; 在本地调试完成后#xff0c;部署到阿里云服务器就一直报错#xff0c; Could not connect to SMTP host: smtp.qiye.aliyun.com, port: 465; 网上也搜索了很多的资料#xff0c;最后花了好几个小时才解决#xff0c; 报错日志如下…最近做了一个发送邮件的功能 在本地调试完成后部署到阿里云服务器就一直报错 Could not connect to SMTP host: smtp.qiye.aliyun.com, port: 465; 网上也搜索了很多的资料最后花了好几个小时才解决 报错日志如下
Send mail failed. Error message : Mail server connection failed; nested exception is javax.mail.MessagingException: Could not connect to SMTP host: smtp.qiye.aliyun.com, port: 465;nested exception is:javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate). Failed messages: javax.mail.MessagingException: Could not connect to SMTP host: smtp.qiye.aliyun.com, port: 465;nested exception is:javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)总结下来可能的原因如下我这里遇到的就属于第四种情况
网络或者端口不通邮箱发件服务器地址端口不正确jdk版本不支持发送邮件代码侧问题
排查定位步骤如下
一、 网络或者端口不通 从提示看就是阿里云邮箱的465端口连接不上一开始以为是阿里云禁止了465端口所以在阿里云控制台的安全组里面给465端口都配置了入方向和出方向但仍旧同样报错。 通过shell命令检查网络和端口都是ok的。有人说阿里云服务器默认是开了465的其实无需特意在安全组规则里面配置465 针对465端口检测显然也是ok的
#不指定TLS版本
openssl s_client -connect smtp.qiye.aliyun.com:465
#指定TLS版本
openssl s_client -connect smtp.qiye.aliyun.com:465 -tls1_2二、邮箱发件服务器地址端口不正确 关于端口方面早期的邮件端口是25但目前大多服务商因为垃圾邮件的原因禁止了25端口所以我这边一开始就用的是465。阿里云服务器也不例外但可以在阿里云控制台申请解封25端口然而是小微服务器一般不给解封的所以即使本地25端口也调试ok也不考虑换25端口作为解决方向。
阿里云的stmp地址除了smtp.qiye.aliyun.com外还有以下两个 smtp.mxhichina.com 465 smtphk.qiye.aliyun.com 80/465 但是经过部署阿里云服务器测试报错是同样的。于是怀疑是阿里云企业邮箱有啥问题或者阿里云的企业邮箱哪里设置的不对头所以另外申请了腾讯企业邮箱 smtp.exmail.qq.com465/587端口进行部署阿里云测试问题依旧。这波操作下来 本地ok上阿里云行不通还是环境的问题需要继续排查。
三、jdk版本不支持 网上有说法高版本的jdk的http安全限制导致发不去邮件。我这里阿里云服务器jdk版本是1.8.0_372 本地是 1.8.0_91都是1.8的jdk小版本不同应该问题不大但也进行了尝试。关于jdk主要是两个方面java.security文件的配置和替换jre目录下的jar包 3.1更改 java.security配置 java.security文件位于jdk安装目录的/jdk1.8.0_372/jre/lib目录下面服务器上忘记或者不知道jdk的安装路径的可以参考如下
which java
ls -lrt /usr/bin/java #其中 /usr/bin/java是第一步的输出结果
ls -lrt /etc/alternatives/java #其中 /etc/alternatives/java是第二步输出的结果
# 如下图可知安装目录是 /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.372.b07-4.0.2.al8.x86_64编辑 java.security文件搜索关键词jdk.tls.disabledAlgorithms找到如下位置
注释原来的3行或者删除其中的 SSLv3、TLSv1、TLSv1.1协议即不禁用这三个加密协议并保存。效果如下
3.2 用低版本jdk的jar替换高版本jdk的jre目录下的jar包 需要替换的jar文件分别是 local_policy.jar和US_export_policy.jar。可以从网上下载低版本的jar或者用本地jdk相同目录下的jar因为本地能发送成功去服务器上进行覆盖。这两个jar包的路径位于jdk安装目录下
/jdk1.8.0_372/jre/lib
或者
/jdk1.8.0_372/jre/lib/jre/lib/security/policy/limited
/jdk1.8.0_372/jre/lib/jre/lib/security/policy/unlimitedjdk1.7版本替换包网上下载地址 点击下载下载后解压后覆盖到上面的路径下
以上两个步骤操作后通过阿里云控制台重启了实例和重启应用服务器报错却依旧。
四、 发送邮件代码侧问题 先看发送邮件核心代码
Properties properties new Properties();
properties.put(mail.smtp.auth, true);
properties.put(mail.smtp.connectiontimeout, String.valueOf(3 * 1000));
properties.put(mail.smtp.timeout, String.valueOf(3 * 1000));
//启用SSL与指定465端口
properties.put(mail.smtp.ssl.enable, true);
properties.put(mail.smtp.socketFactory.port, 465);
properties.put(mail.smtp.port, 465);
// SSL来建立连接失败则回退兼容。如果出于某种原因无法使用SSL来建立连接比如服务器不支持则不会回退到非加密的连接方式而是让连接尝试失败。
properties.put(mail.smtp.ssl.socketFactory, javax.net.ssl.SSLSocketFactory);
properties.put(mail.smtp.socketFactory.fallback, false);这段代码本地ok上阿里云服务器就连不通stmp465故而又从网上找了几个别人写的发送邮件的工具类代码都是大同小异结果也是本地ok阿里云服务器不行着实让人有点蒙圈。后来添加下面这行指定了ssl的加密协议才解决问题
// 握手阶段加密算法不匹配jre高版本把加密算法禁止了 SSLv3, TLSv1, TLSv1.1等尝试指定jdk版本或删除相关禁用配置项props.setProperty(mail.smtp.ssl.protocols, TLSv1.2); 下面附录一个发送邮件的工具类以供参考和测试
package com.yulisao.utils.email;import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.security.Security;
import java.util.Date;
import java.util.Properties;public class EmailUtils{// 此方法调试ok后自行整理成工具类应用到项目中public static void sendmail() {try{//设置SSL连接、邮件环境Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());final String SSL_FACTORY javax.net.ssl.SSLSocketFactory;Properties props System.getProperties();//协议//props.setProperty(mail.transport.protocol, smtp);props.setProperty(mail.smtp.host, smtp.qiye.aliyun.com);//smtp服务器地址//props.setProperty(mail.smtp.port, 25);//非加密端口// 使用ssl加密方式进行如下配置props.setProperty(mail.smtp.socketFactory.class, SSL_FACTORY);props.setProperty(mail.smtp.socketFactory.fallback, false);props.setProperty(mail.smtp.socketFactory.port, 465);// 不指定则是25端口了注意阿里云禁用此端口props.setProperty(mail.smtp.port, 465);props.setProperty(mail.smtp.ssl.enable, true);props.setProperty(mail.smtp.ssl.protocols, TLSv1.2);props.setProperty(mail.smtp.auth, true);//表示SMTP发送邮件需要进行身份验证props.setProperty(mail.smtp.from, 你的发件邮箱);//mailfrom 参数props.setProperty(mail.user,你的发件邮箱);//发件人的账号props.setProperty(mail.password,你的发件邮箱的授权码);// 发件人的账号的密码如果开启三方客户端安全密码请使用新生产的密码System.setProperty(mail.mime.splitlongparameters, false); //用于解决附件名过长导致的显示异常//建立邮件会话Session session Session.getDefaultInstance(props, new Authenticator() {//身份认证protected PasswordAuthentication getPasswordAuthentication() {//发件人的账号、密码String userName props.getProperty(mail.user);String password props.getProperty(mail.password);return new PasswordAuthentication(userName, password);}});//建立邮件对象MimeMessage message new MimeMessage(session);//设置邮件的发件人InternetAddress from new InternetAddress(你的发件邮箱,你的邮件主题); //from 参数,可实现代发注意代发容易被收信方拒信或进入垃圾箱。message.setFrom(from);//设置邮件的收件人String[] to {abc163.com,123456789qq.com};//收件人列表InternetAddress[] sendTo new InternetAddress[to.length];for (int i0;ito.length;i){System.out.println(正在执行发送到 to[i]);sendTo[i] new InternetAddress(to[i]);}//传入收件人message.setRecipients(Message.RecipientType.TO,sendTo);//设置邮件的主题message.setSubject(邮件主题);//设置邮件的文本String content邮件内容;message.setContent(content,text/html;charsetUTF-8);//设置时间message.setSentDate(new Date());message.saveChanges();//发送邮件Transport.send(message);System.out.println(发送成功);}catch(Exception e){System.out.println(发送邮件异常e.toString());}}// 自测main方法public static void main(String[] args) {try{//设置SSL连接、邮件环境Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());final String SSL_FACTORY javax.net.ssl.SSLSocketFactory;Properties props System.getProperties();//协议//props.setProperty(mail.transport.protocol, smtp);props.setProperty(mail.smtp.host, smtp.qiye.aliyun.com);//smtp服务器地址//props.setProperty(mail.smtp.port, 25);//非加密端口// 使用ssl加密方式进行如下配置props.setProperty(mail.smtp.socketFactory.class, SSL_FACTORY);props.setProperty(mail.smtp.socketFactory.fallback, false);props.setProperty(mail.smtp.socketFactory.port, 465);props.setProperty(mail.smtp.ssl.enable, true);props.setProperty(mail.smtp.ssl.protocols, TLSv1.2);props.setProperty(mail.smtp.auth, true);//表示SMTP发送邮件需要进行身份验证props.setProperty(mail.smtp.from, 你的发件邮箱);//mailfrom 参数props.setProperty(mail.user,你的发件邮箱);//发件人的账号props.setProperty(mail.password,你的发件邮箱的授权码);// 发件人的账号的密码如果开启三方客户端安全密码请使用新生产的密码System.setProperty(mail.mime.splitlongparameters, false); // 用于解决附件名过长导致的显示异常//建立邮件会话Session session Session.getDefaultInstance(props, new Authenticator() {//身份认证protected PasswordAuthentication getPasswordAuthentication() {//发件人的账号、密码String userName props.getProperty(mail.user);String password props.getProperty(mail.password);return new PasswordAuthentication(userName, password);}});//建立邮件对象MimeMessage message new MimeMessage(session);//设置邮件的发件人InternetAddress from new InternetAddress(你的发件邮箱,你的邮件主题); //from 参数,可实现代发注意代发容易被收信方拒信或进入垃圾箱。message.setFrom(from);//设置邮件的收件人String[] to {abc163.com,123456789qq.com};//收件人列表InternetAddress[] sendTo new InternetAddress[to.length];for (int i0;ito.length;i){System.out.println(正在执行发送到 to[i]);sendTo[i] new InternetAddress(to[i]);}//传入收件人message.setRecipients(Message.RecipientType.TO,sendTo);//设置邮件的主题message.setSubject(邮件主题);//设置邮件的文本String content邮件内容;message.setContent(content,text/html;charsetUTF-8);//设置时间message.setSentDate(new Date());message.saveChanges();//发送邮件Transport.send(message);System.out.println(发送成功);}catch(Exception e){System.out.println(发送邮件异常e.toString());}}
}