javaMail的使用以及trying to connect to host "1xxx@163.com", port 25, isSSL false异常

本文详细介绍使用JavaMail API通过SMTP协议发送邮件的具体步骤。从添加pom依赖开始,逐步讲解如何配置邮件服务器、创建邮件实例并发送邮件。文章提供完整的代码示例,包括设置邮件主题、正文及发送时间。

最近项目用到邮件系统,开始了解javaMail。。。话不多说先上代码:

pom依赖:

    <!--    邮件  https://mvnrepository.com/artifact/javax.mail/mail -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.5.0-b01</version>
        </dependency>

工具类:

 import java.util.Date;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MailUtils {
    //发件人地址
    private static String senderAddress = "1234567891@163.com";
    //收件人地址
    private static String recipientAddress  = "123456789@qq.com";
    //发件人账户
    public static String senderAccount = "1234567891@163.com";
    //发件人授权码
    public static String auth = "xxxxxxx";
    //邮件主题
    public static String subject = "xxxxxx通知";
    //邮件正文
    public static String content = "您有一则xxxxx!";
    
    public static void main(String [] args) throws MessagingException {
        //1.连接邮件服务器的配置参数
        Properties properties = new Properties();
        //设置用户认证方式
        properties.setProperty("mail.smtp.auth", "true");
        //设置传输协议
        properties.setProperty("mail.transport.protocol", "smtp");
        //设置发件人的SMTP服务器地址
        properties.setProperty("mail.smtp.host", "smtp.163.com");
        //properties.setProperty("mail.smtp.port", "465");
        
        //2.创建定义整个应用程序所需的环境信息的Session对象
        Session session = Session.getInstance(properties);
        session.setDebug(true);
        //3.创建邮件的实例对象
        MimeMessage msg = getMimeMessage(session);
        //4.根据session对象获取邮件传输对象
        Transport transport = session.getTransport("smtp");
        transport.connect("smtp.163.com", senderAccount, auth);
        //发送邮件,并发送到所有收件人地址,message.getAllRecipients()获取到创建又见对象时添加的所有收件人抄送人密送人
        transport.sendMessage(msg, msg.getAllRecipients());
        //如果只想发送给指定的人,可以如下写法
        //transport.sendMessage(msg, new Address[]{new InternetAddress("xxx@qq.com")});
        //5.关闭邮件链接
        transport.close();
        
    }
    
        /**
         * 獲得創建一封郵件的實例對象
         * @param session
         * @return
         * @throws MessagingException
         * @throws AddressException
         */
        public static MimeMessage getMimeMessage(Session session) throws MessagingException {
            //創建郵件的實例對象
            MimeMessage msg = new MimeMessage(session);
            //设置发件人地址
            msg.setFrom(new InternetAddress(senderAddress));
            
            /*
             * 设置收件人地址(可以增加多个收件人,抄送人,密送)
             * MimeMessage.RecipientType.TO 发送
             * MimeMessage.RecipientType.CC 抄送
             * MimeMessage.RecipientType.BCC 密送
             */
            msg.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(recipientAddress));
            //设置邮件主题
            msg.setSubject(subject, "UTF-8");
            //设置邮件正文
            msg.setContent(content, "text/html;charset=UTF-8");
            //设置邮件的发送时间默认立即发送
            msg.setSentDate(new Date());
            return msg;
        }
}

需要注意首先发件人邮箱需要设置开启POP3/SMTP/IMAP协议

 transport.connect("smtp.163.com", senderAccount, auth);这里的参数注意第三个不是密码

转载于:https://www.cnblogs.com/qq642193463/p/10691516.html

<think>我们正在解决SMTP连接日志中提示'trying to connect to host "smtp.163.com", port 587, isSSL false'的问题。根据引用内容,常见问题包括连接超时、端口不通、SSL配置不正确等。特别是引用[1][2][3]都提到了连接超时(Connection timed out)的问题,引用[3][4][5]则提到了使用SSL和端口465的成功经验。 ### 问题分析 1. **端口587与25的阻塞问题**:引用[1][2]显示,在阿里云服务器上使用端口25发送邮件时出现连接超时。这是因为阿里云默认禁止了出方向的25端口(SMTP传统非加密端口)。同样,端口587(用于STARTTLS)也可能被云服务商限制。 2. **SSL加密要求**:引用[3][4]指出,163邮箱要求使用加密连接(端口465或587+STARTTLS),但日志显示当前连接尝试使用非加密(isSSL=false)。 3. **服务器环境差异**:引用[2]提到本地测试成功而生产环境失败,说明云服务器网络策略不同。 4. **协议配置问题**:引用[5]提到Java安全配置文件(java.security)可能禁用了某些协议,导致SSL连接失败。 ### 解决方案 #### 1. 改用加密端口(推荐465端口) 根据引用[3][4],163邮箱推荐使用加密端口465(SSL/TLS): ```java Properties props = new Properties(); props.put("mail.smtp.host", "smtp.163.com"); props.put("mail.smtp.port", "465"); // 使用465端口 props.put("mail.smtp.ssl.enable", "true"); // 启用SSL props.put("mail.smtp.auth", "true"); // 必须认证 ``` #### 2. 配置SSL套接字工厂(解决协议兼容性) 引用[3][5]建议指定SSL协议版本(如TLSv1.2): ```java props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.ssl.protocols", "TLSv1.2"); // 明确协议版本 ``` #### 3. 检查云服务器安全组 - 登录阿里云/腾讯云控制台,在**安全组规则**中开放**出方向**的465端口(TCP协议)。 - 如果使用587端口,需同时开启587并配置STARTTLS(但465更稳定)。 #### 4. 修改Java安全策略(可选) 如果仍报SSL错误,按引用[5]修改`$JAVA_HOME/conf/security/java.security`: ```diff - jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1 + jdk.tls.disabledAlgorithms=SSLv3 # 仅禁用SSLv3 ``` ### 完整代码示例 ```java import cn.hutool.extra.mail.MailAccount; import cn.hutool.extra.mail.MailUtil; public class EmailSender { public static void main(String[] args) { MailAccount account = new MailAccount(); account.setHost("smtp.163.com"); account.setPort(465); // 关键:465端口 account.setAuth(true); account.setFrom("your_email@163.com"); account.setUser("your_email@163.com"); // 发件人邮箱 account.setPass("your_auth_code"); // 授权码非密码 account.setSslEnable(true); // 启用SSL MailUtil.send(account, "recipient@example.com", "Subject", "Content", false); } } ``` ### 验证步骤 1. **本地测试**:确保代码在本地可发送邮件(检查163邮箱的SMTP服务已开启并获取授权码)。 2. **服务器测试**: - 在服务器执行`telnet smtp.163.com 465`验证网络连通性。 - 如果超时,检查安全组和防火墙。 3. **日志分析**:启用JavaMail DEBUG日志,确认连接过程: ```log DEBUG: trying to connect to host "smtp.163.com", port 465, isSSL true DEBUG: connected to host "smtp.163.com", port: 465 ``` ### 常见错误处理 | 错误现象 | 解决方案 | |---------|---------| | `Connection timed out` | 开放云服务器出方向465端口 | | `Authentication failed` | 检查邮箱授权码(非登录密码)[^3] | | `javax.net.ssl.SSLHandshakeException` | 更新`java.security`文件或升级JDK | > **注意**:163邮箱要求使用**授权码**而非邮箱密码进行SMTP认证,需在邮箱设置中生成[^4]。 通过以上调整,可解决端口587连接问题。优先使用465端口可避开云服务商对25/587端口的限制。 §§相关问题§§ 1. 如何为163邮箱生成SMTP授权码? 2. 阿里云服务器如何配置安全组规则开放465端口? 3. JavaMail中`mail.smtp.ssl.protocols`参数的作用是什么? 4. 使用Telnet测试SMTP服务器连通性的具体步骤? 5. STARTTLS和SMTPS(SSL)协议的区别及适用场景? [^1]: 引用[1]显示端口25连接超时,说明传统端口被阻断 [^2]: 引用[2]同样在阿里云服务器出现端口25超时,证明云环境限制 [^3]: 引用[3]提供465端口SSL连接方案,成功避开端口封锁 [^4]: 引用[4]验证Hutool工具类简化SSL邮件发送 [^5]: 引用[5]指出Java安全配置可能影响TLS协议协商</think>### 解决 SMTP 连接日志提示 "trying to connect to host smtp.163.com port 587 isSSL false" 问题 #### 问题核心原因分析 1. **端口与加密协议不匹配** - 163 邮箱要求使用加密连接(SSL/TLS),但日志显示 `isSSL=false`,表明未启用加密 - 163 邮箱官方推荐端口:465(SSL)或 994(TLS)[^3][^4] 2. **云服务器端口限制** - 阿里云/腾讯云等默认**封锁出站25和587端口**(防垃圾邮件策略)[^1][^2] - 本地可连接但服务器失败,证明是云环境限制 3. **SSL配置缺失** - 未正确配置加密协议参数(需显式启用 SSL/TLS)[^3] 4. **协议版本兼容性问题** - JDK 安全策略可能禁用老旧协议(如 TLSv1.0)[^5] --- ### 完整解决方案 #### 步骤 1:改用加密端口(推荐 465) ```java // 在 Properties 中配置加密参数 Properties props = new Properties(); props.put("mail.smtp.host", "smtp.163.com"); props.put("mail.smtp.port", "465"); // 关键修改:使用 465 端口 props.put("mail.smtp.ssl.enable", "true"); // 显式启用 SSL props.put("mail.smtp.auth", "true"); // 指定 TLSv1.2 协议(解决兼容性问题)[^5] props.put("mail.smtp.ssl.protocols", "TLSv1.2"); ``` #### 步骤 2:配置 SSL 套接字工厂 ```java // 添加 SSL 套接字工厂配置 props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); props.put("mail.smtp.socketFactory.port", "465"); ``` #### 步骤 3:云服务器安全组配置 1. **登录云控制台**(阿里云/腾讯云等) 2. **安全组规则** → **添加出站规则**: - 协议:`TCP` - 端口范围:`465` - 目标:`0.0.0.0/0` - 策略:`允许` #### 步骤 4:连接测试代码 ```java Transport transport = session.getTransport("smtp"); try { // 使用加密端口连接 transport.connect("smtp.163.com", 465, "your_email@163.com", "auth_code"); transport.sendMessage(message, message.getAllRecipients()); } finally { transport.close(); } ``` --- ### 验证成功的配置参数 | 参数 | 值 | 说明 | |------|----|------| | `mail.smtp.host` | smtp.163.com | SMTP服务器地址 | | `mail.smtp.port` | 465 | 加密端口 | | `mail.smtp.ssl.enable` | true | 启用SSL加密 | | `mail.smtp.auth` | true | 启用认证 | | `mail.smtp.ssl.protocols` | TLSv1.2 | 协议版本 | | `mail.smtp.socketFactory.class` | javax.net.ssl.SSLSocketFactory | SSL工厂类 | --- ### 常见错误处理 1. **仍出现连接超时** ```bash # 在服务器执行端口测试 telnet smtp.163.com 465 ``` - 若失败 → 检查云服务器安全组和防火墙 - 若成功 → 检查代码参数配置 2. **证书验证错误** 在测试环境可临时添加(生产环境需正式证书): ```java props.put("mail.smtp.ssl.trust", "*"); ``` 3. **认证失败** - 确认使用**授权码**而非邮箱密码(需在163邮箱设置中生成) - 检查用户名格式:`full_email@163.com`(完整邮箱地址) --- ### 使用 Hutool 简化配置(推荐) ```xml <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.20</version> </dependency> ``` ```java MailAccount account = new MailAccount(); account.setHost("smtp.163.com"); account.setPort(465); // 加密端口 account.setFrom("your_email@163.com"); account.setUser("your_email@163.com"); // 完整邮箱 account.setPass("your_auth_code"); // 授权码 account.setSslEnable(true); // 启用SSL // 发送邮件 MailUtil.send(account, "recipient@example.com", "主题", "内容", false); ``` > **实测结果**:使用465端口 + SSL配置后,连接日志应显示: > `DEBUG: trying to connect to host "smtp.163.com", port 465, isSSL true` > `DEBUG: connected to host "smtp.163.com", port: 465`[^3][^4]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值