【问题标题】:JavaMail smtp properties (for STARTTLS)JavaMail smtp 属性(用于 STARTTLS)
【发布时间】:2011-08-01 07:36:19
【问题描述】:

JavaMail 指定了一组可以设置为配置 SMTP 连接的属性。要使用 STARTTLS,需要设置以下属性

mail.smtp.starttls.enable=true

在哪里指定用户名/密码以使用 smtp 服务?是否足以指定:

mail.smtp.user=me
mail.smtp.password=secret

或者我必须使用以下方式显式登录:

transport.connect(server, userName, password)

是的,我已经尝试过这样做,似乎有必要使用transport.connect(..) 进行连接。但如果是的话,mail.smtp.user & pass 属性是干什么用的?他们还不足以将 smtp 与starttls 一起使用吗?

【问题讨论】:

    标签: java smtp jakarta-mail starttls


    【解决方案1】:

    这是我的 sendEmail 方法,它使用带有 STARTTLS 的 GMail smtp (JavaMail)

    public void sendEmail(String body, String subject, String recipient) throws MessagingException,
                UnsupportedEncodingException {
            Properties mailProps = new Properties();
            mailProps.put("mail.smtp.from", from);
            mailProps.put("mail.smtp.host", smtpHost);
            mailProps.put("mail.smtp.port", port);
            mailProps.put("mail.smtp.auth", true);
            mailProps.put("mail.smtp.socketFactory.port", port);
            mailProps.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
            mailProps.put("mail.smtp.socketFactory.fallback", "false");
            mailProps.put("mail.smtp.starttls.enable", "true");
    
            Session mailSession = Session.getDefaultInstance(mailProps, new Authenticator() {
    
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(login, password);
                }
    
            });
    
            MimeMessage message = new MimeMessage(mailSession);
            message.setFrom(new InternetAddress(from));
            String[] emails = { recipient };
            InternetAddress dests[] = new InternetAddress[emails.length];
            for (int i = 0; i < emails.length; i++) {
                dests[i] = new InternetAddress(emails[i].trim().toLowerCase());
            }
            message.setRecipients(Message.RecipientType.TO, dests);
            message.setSubject(subject, "UTF-8");
            Multipart mp = new MimeMultipart();
            MimeBodyPart mbp = new MimeBodyPart();
            mbp.setContent(body, "text/html;charset=utf-8");
            mp.addBodyPart(mbp);
            message.setContent(mp);
            message.setSentDate(new java.util.Date());
    
            Transport.send(message);
        }
    

    【讨论】:

    • 嗨。你在哪里输入实际的用户名和密码?
    • 在 Authenticator 类的 getPasswordAuthentication() 方法中
    • 嗯,当我设置“...socketFactory.class”时,它似乎使用 SSL over SMTP 而不是 StartTLS,我收到“无法识别的 SSL 消息,明文连接?”例外。
    【解决方案2】:

    您必须继承 Authenticator 并为 Session 创建一个 PasswordAuthentication 对象以及用于登录的 env 属性

    Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
    
        protected PasswordAuthentication getPasswordAuthentication() {
          return new PasswordAuthentication("user-name", "user-password");
        }
      });
    

    用户名有时是某些服务器(如 gmail)的完整电子邮件 ID。 希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      你可以指定用户为

      mail.smtps.user=cayhorstmann@gmail.com
      

      (或mail.smtp.user,如果您不使用mail.transport.protocol=smtps)在您用于会话的属性中。

      AFAIK,您无法提供密码。但是你当然可以把它放在道具里,然后自己取回来。或者以其他方式获取它,例如通过提示用户。

      当你拥有它时,有两种方法可以将它提供给会话。比较简单的就是使用

      Transport tr = session.getTransport();
      tr.connect(null, password);
      tr.sendMessage(message, message.getRecipients());
      

      或者,正如所指出的,您可以使用身份验证器。但是随后来自道具的用户被忽略了,您必须将其显式传递给PasswordAuthentication。如果你这样做了,那么你的奖励就是你可以使用静态的Transport.send

      【讨论】:

        【解决方案4】:

        您必须在创建会话时提供身份验证器

        Authenticator authenticator = new PasswordAuthentication("username", "password");
        Session session = Session.getInstance(properties, authenticator);
        

        然后您使用会话发送消息(为简洁起见,跳过 try/catch):

        SMTPTransport tr = (SMTPTransport) session.getTransport("smtps");
        tr.connect();
        tr.sendMessage(mimeMessage, mimeMessage.getAllRecipients());
        

        【讨论】:

        • JavaMail FAQ 所述,使用身份验证器是可选的并且通常是混乱的。
        【解决方案5】:

        使用Simple Java Mail 应该很简单:

        Email email = new Email();
        
        email.setFromAddress("lollypop", "lol.pop@somemail.com");
        email.addRecipient("C.Cane", "candycane@candyshop.org", RecipientType.TO);
        email.setText("We should meet up!");
        email.setTextHTML("<b>We should meet up!</b>");
        email.setSubject("hey");
        
        new Mailer("smtp.gmail.com", 25, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
        new Mailer("smtp.gmail.com", 587, "your user", "your password", TransportStrategy.SMTP_TLS).sendMail(email);
        new Mailer("smtp.gmail.com", 465, "your user", "your password", TransportStrategy.SMTP_SSL).sendMail(email);
        

        如果您启用了双因素登录,则需要从您的 Google 帐户生成application specific password


        如果你还想自己做,code behind this 库非常简单。它根据传递的TransportStrategy(普通、ssl 或 tls)在 Session 上设置特定属性,并使用 Authenticator 执行身份验证:

        "mail.transport.protocol" : "smtp"
        "mail.smtp.starttls.enable" : "true"
        "mail.smtp.host" : host
        "mail.smtp.port" : port
        "mail.smtp.username" : username
        "mail.smtp.auth" : "true"
        

        return Session.getInstance(props, new Authenticator() {
           @Override
           protected PasswordAuthentication getPasswordAuthentication() {
              return new PasswordAuthentication(username, password);
           }
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-21
          • 2022-01-18
          • 2013-06-21
          • 1970-01-01
          • 2013-08-21
          相关资源
          最近更新 更多