You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat9环境下JSP密码恢复系统JavaMail SSL握手异常求助

Java JSP项目Tomcat部署下JavaMail SSL握手错误排查

我正在开发部署于Tomcat 9的Java JSP项目,采用PostgreSQL存储数据,核心功能是通过JavaMail API实现密码恢复邮件发送,但持续遭遇SSL握手错误导致邮件发送失败。

项目环境配置

  • Java版本:OpenJDK 21.0.4 LTS (Temurin)
openjdk version "21.0.4" 2024-07-16 LTS
OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode, sharing)
  • 技术栈:JSP+Java Servlet实现前后端逻辑
  • 服务器:Windows环境Tomcat 9,配置如下:
    • JRE路径:C:\Program Files\Java\jdk1.7.0_80\jre
    • JDK路径:C:\Program Files\Java\jdk1.7.0_80
    • Tomcat路径:C:\Program Files\Apache Software Foundation\Tomcat 9.0
    • Catalina配置路径:C:\Program Files\Apache Software Foundation\Tomcat 9.0\conf\Catalina
  • 数据库:PostgreSQL 42.2.29驱动(PostgreSQL JDBC)

核心错误信息

javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
    at sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:171)
    at sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:101)
    at sun.security.ssl.TransportContext.kickstart(TransportContext.java:238)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:394)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373)
    at com.sun.mail.util.SocketFetcher.configureSSLSocket(SocketFetcher.java:549)
    at com.sun.mail.util.SocketFetcher.createSocket(SocketFetcher.java:354)
    at com.sun.mail.util.SocketFetcher.getSocket(SocketFetcher.java:237)
    at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1927)

使用的依赖库

  • PostgreSQL JDBC (postgresql-42.2.29.jre7.jar)
  • Bcrypt (jbcrypt-0.4.jar)
  • JavaMail API (mail-1.4.7.jar, smtp-1.6.2.jar, javax.activation.jar)
  • 安全策略包(US_export_policy.jar, local_policy.jar)
  • 额外添加库:US_export_policy.jar、bcrypt-0.4.1.jar等共9个JAR包

邮件发送核心代码(RECOVERY_ACCOUNT.JSP)

// THIS IS THE MAIN CODE THAT IS SENDING EMAILS (RECOVERY_ACCOUNT.JSP)

    // Database connection configurations
    String url = "jdbc:postgresql://localhost:5432/bibliotech";
    String user = "postgres";
    String password = "admin";
    
    String email = request.getParameter("email");
    String passwordHash = null;
    
    try {
        // Connect to the database
        Class.forName("org.postgresql.Driver");
        Connection conn = DriverManager.getConnection(url, user, password);
        // Query to check if the email exists
        String query = "SELECT password_hash FROM USERS WHERE email = ?";
        PreparedStatement pstmt = conn.prepareStatement(query);
        pstmt.setString(1, email);
        ResultSet rs = pstmt.executeQuery();
    
        if (rs.next()) {
            passwordHash = rs.getString("password_hash");  // Retrieve the password hash
        } else {
            out.println("<script>alert('Email not found!'); window.location.href = 'recovery.jsp';</script>");
        }
    
        rs.close();
        pstmt.close();
        conn.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    // If the password hash was found, send an email to the user
    if (passwordHash != null) {
        // JavaMail configurations
        String host = "smtp.gmail.com";  // Using Gmail as an example
        String from = "bibliotechproject@gmail.com"; // Your email
        String appPassword = "************";  // Use a Gmail app password
        String to = email;
        String subject = "Password Recovery - Bibliotech";
    
        // Email content with HTML
        String messageText = 
        "<div style='font-family: Arial, sans-serif; padding: 20px; background-color: #f4f4f4;'>"
            + "<center>"
                + "<img src='https://iili.io/dPzedMX.png' alt='Account Recovery' style='width: 100%; max-width: 600px; height: auto;'>"
                + "<div style='background-color: #ffffff; padding: 20px; border-radius: 8px; max-width: 600px; text-align: left;'>"
                    + "<h2 style='color: #333;'>Account Recovery</h2>"
                    + "<p style='color: #555;'>Hello,</p>"
                    + "<p style='color: #555;'>We received a request to recover the password for your account. Here are your login details:</p>"
                    + "<p style='font-weight: bold; color: #333;'>Email: " + email + "</p>"
                    + "<p style='font-weight: bold; color: #333;'>Password: " + passwordHash + "</p>"
                    + "<p style='color: #555;'>If you did not make this request, please ignore this email.</p>"
                    + "<p style='color: #555;'>Sincerely, https://prod.liveshare.vsengsaas.visualstudio.com/join?01A2BDE3A14A18BC1D1E0892E16E13D31189</p>"
                    + "<p style='color: #333; font-weight: bold;'>Support Team - Bibliotech</p>"
                + "</div>"
            + "</center>"
        + "</div>";
    
        Properties props = System.getProperties();
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.user", from);
        props.put("mail.smtp.password", appPassword);
        props.put("mail.smtp.port", "587");
        props.put("mail.debug", "true");
        props.put("mail.smtp.ssl.enable", "true");
        props.put("mail.smtp.auth", "true");
    
        Session mailSession = Session.getDefaultInstance(props, null);
        MimeMessage message = new MimeMessage(mailSession);
    
        try {
            message.setFrom(new InternetAddress(from));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
    
            message.setSubject(subject);
            message.setContent(messageText, "text/html");
    
            Transport transport = mailSession.getTransport("smtp");
            transport.connect(host, from, appPassword);
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
    
            response.sendRedirect("send_success.jsp");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

已尝试措施

  • 确认服务器及JavaMail配置启用正确SSL协议
  • 更新JavaMail库尝试解决SSL协议不匹配
  • 检查JAR包顺序排查冲突

疑问

  • 异常是否与Java21版本、JavaMail或Tomcat配置有关?
  • 是否因旧版JAR包导致SSL协议冲突?
  • 同类问题的解决方案是什么?
  • 正确的依赖版本及顺序是怎样的?

此外,曾有一天无需修改即可正常发送邮件,次日同一机器再次出现错误,怀疑与Java配置相关。


内容的提问来源于stack exchange,提问作者JonathanDEVOPS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 18:24:52