【问题标题】:Sending an email in Java with commons-mail使用 commons-mail 在 Java 中发送电子邮件
【发布时间】:2015-09-29 00:58:04
【问题描述】:

所以我正在尝试使用 Java 将代码发送到我的电子邮件。我从 javax.mail 开始,但记得我上次使用它时遇到了问题,所以我转向了 Apache Commons Mail。

不过,我遇到了一堆错误。在 SSL 上,我收到了 java.net.SocketTimeoutException,在 TLS 上,我收到了一些错误:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2000)

Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

当我在 Google 上进行快速搜索时,我找到了this question。现在因为我是个彻头彻尾的白痴,所以我不明白答案。

我可以做些什么来解决这些错误?无论是防止 SSL 超时还是其他 TLS 超时。

编辑:我发送电子邮件没有问题,MessageException 不是我的问题,所以请停止回答。

【问题讨论】:

  • 发布您的代码!您使用哪个邮件提供商发送邮件?
  • @kevcodez 我正在使用 GMail。不过,我认为这部分实际上并不相关。

标签: java email ssl


【解决方案1】:

据我所知,发送电子邮件也有类似的问题。

我将展示org.springframework.mail.javamail.JavaMailSenderImpl 的示例。基本上有几种处理这种情况的方法。您找到的答案也可以使用,但可以在 JVM 级别上使用。 我没有像您发现的那样停止使用 JVM 方法。

应该怎么做

添加主机(例如让我们看看 gmail 主机:smtp.gmail.com)。通过将主机添加到受信任的 - 一切都开始按预期工作。就我而言,我必须将此主机添加到

Part of spring xml configuration

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="${mail.host}"/>
    <property name="port" value="${mail.port}"/>
    <property name="username" value="${mail.username}"/>
    <property name="password" value="${mail.password}"/>
    <property name="javaMailProperties">
        <props>
            <prop key="mail.transport.protocol">${mail.transport.protocol}</prop>
            <prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
            <prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable}</prop>
            <prop key="mail.smtp.ssl.trust">${mail.smtp.ssl.trust}</prop>
        </props>
    </property>
</bean>

Properties file

mail.host=smtp.gmail.com
mail.port=587
mail.username=user@gmail.com
mail.password=password
mail.transport.protocol=smtp
mail.smtp.auth=true
mail.smtp.starttls.enable=true
mail.smtp.ssl.trust=smtp.gmail.com

请注意,如果是 gmail,您应该从 安全控制台 授予适当的权限

更新

你有没有机会从Apache Common Email官网尝试下面的代码:

Email email = new SimpleEmail();
email.setHostName("smtp.googlemail.com");
email.setSmtpPort(465);
email.setAuthenticator(new DefaultAuthenticator("username", "password"));
email.setSSLOnConnect(true);
email.setFrom("user@gmail.com");
email.setSubject("TestMail");
email.setMsg("This is a test mail ... :-)");
email.addTo("foo@bar.com");
email.send();

【讨论】:

  • 这是我使用的确切代码(关于 Commons-Email)。但不排序任何东西。
  • 您是否这样做过:考虑到您应该从安全控制台授予适当的 gmail 权限。
  • 我不明白你的意思,但我使用了正确的用户名和密码。
  • 还可以访问此链接google.com/settings/security/lesssecureapps 并启用对您帐户的访问权限。它应该可以解决您的问题。
  • 我的帐户启用了两步验证,所以我有一个应用密码。
【解决方案2】:
Email email = new SimpleEmail();
...

// add this line
email.getMailSession().getProperties().put("mail.smtp.ssl.trust", "smtp.gmail.com");

...
email.send();

【讨论】:

  • 这个答案出现在 SO.. 的低质量帖子中。你能在你的答案中添加任何评论吗?解释你的逻辑,并对你的代码打算做什么做一点评论。这将有助于 OP,但它也将作为未来用户的评论
【解决方案3】:

使用版本 1.5.0-b01 的库 javax.mail 你会发现有一种简单的方法可以避免这种错误。这是我前一段时间使用的示例,效果很好:

        Properties props = new Properties();
        MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
        socketFactory.setTrustAllHosts(true);
        props.put("mail.imaps.ssl.socketFactory", socketFactory);

如果你使用的是 maven,你可以添加这个依赖:

 <dependency>
  <groupId>javax.mail</groupId>
  <artifactId>mail</artifactId>
  <version>1.5.0-b01</version>
</dependency>

【讨论】:

    【解决方案4】:

    我遇到了同样的错误,这是解决方法

    添加这一行:props.put("mail.smtp.ssl.trust", "smtp.gmail.com");

    参考:http://javainfinite.com/java/send-email-using-gmail-in-java/

    【讨论】:

      【解决方案5】:

      为了解决 java 6 中持续存在的 ssl 握手问题。从 java 7.get certificateds 获得证书文件具有忽略证书身份验证的能力。

      从以下 java 7 目录复制“cacerts”文件

      C:\Program Files\Java\jdk1.7.0_79\jre\lib\security

      粘贴进去

      C:\Program Files\Java\jdk1.6.0\jre\lib\security

      【讨论】:

        【解决方案6】:

        错误

        PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 
        

        是证书链坏了。这意味着提供者可能正在使用客户端系统不信任的自签名证书。 受信任的证书存储在 C:\Program Files\Java\jdk1.6.0\jre\lib\security 中的 cacerts 中,如上面的答案中所述。

        对此的解决方案可能是将缺少的根证书或中间证书添加到 cacerts。当然,如果您信任提供这些证书的主机,您就会这样做。即通常公司倾向于创建自己的证书供内部使用。

        【讨论】:

          猜你喜欢
          • 2012-12-11
          • 2010-10-25
          • 1970-01-01
          • 2015-03-21
          • 2015-06-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-04-19
          相关资源
          最近更新 更多