簡體   English   中英

無法使用Javamail通過SSL或TLS使用SMTP發送郵件

[英]Can't send mail via SSL or TLS using SMTP using Javamail

新年快樂!

我正在開發一個應用程序,用戶只要發生特定觸發器就會收到電子郵件。

這是我用來發送電子郵件的功能:

public static void sendEmail(String host, String port, String useSSL, String useTLS, String useAuth, String user, String password, String subject, String content, String type, String recipients)
            throws NoSuchProviderException, AddressException, MessagingException  {
        final Properties props = new Properties();
        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtp.host", host);
        props.setProperty("mail.smtp.port", port);        
        if (useSSL != null && !useSSL.equals("false") && useSSL.equals("true")) {
            props.setProperty("mail.smtp.ssl.enable", useSSL);
            props.setProperty("mail.smtp.socketFactory.class",
                    "javax.net.ssl.SSLSocketFactory");
            props.setProperty("mail.smtp.socketFactory.port", port);

        }
        if (useTLS != null && !useTLS.equals("false") && useTLS.equals("true")) {
            props.setProperty("mail.smtp.starttls.enable", useTLS);
            props.setProperty("mail.smtp.socketFactory.fallback", "true");
        }   
        props.setProperty("mail.smtp.auth", useAuth);
        props.setProperty("mail.from", user);  
        props.setProperty("mail.smtp.user", user);
        props.setProperty("mail.password", password);

        Session mailSession = Session.getDefaultInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(props.getProperty("mail.smtp.user"), props
                        .getProperty("mail.password"));
            }
        });   

        Transport transport = mailSession.getTransport();

        MimeMessage message = new MimeMessage(mailSession);
        message.setHeader("Subject", subject);
        message.setContent(content, type);

        StringTokenizer tokenizer = new StringTokenizer(recipients, ";");
        while (tokenizer.hasMoreTokens()) {
            String recipient = tokenizer.nextToken();
            message.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(recipient));
        }

        transport.connect();
        transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
        transport.close();

奇怪的是,每當我嘗試使用main方法運行上述代碼時,它都會成功發送SSL和TLS協議的電子郵件。

public static void main(String args[])
    {
        try {
            Notifier.sendEmail("smtp.gmail.com", "587", "false", "true", "true","sender_email@gmail.com", "testpassword", "CHECKING SETTINGS", "CHECKING EMAIL FUNCTIONALITY", "text/html", "cc_email@gmail.com");
        } catch (Exception ex) {
            ex.printStackTrace();
        } 
    }

但每當我嘗試通過我的Web應用程序運行相同的代碼時它就會失敗。

通過SSL發送它會引發此錯誤:

com.sun.mail.smtp.SMTPSendFailedException: 530-5.5.1 Authentication Required. Learn more at
jvm 1    | 530 5.5.1  https://support.google.com/mail/answer/14257 f12sm88286300pat.20 - gsmtp
jvm 1    | 
jvm 1    |  at com.sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.java:2057)

通過TLS發送會拋出此錯誤:

javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 587;
jvm 1    |   nested exception is:
jvm 1    |  javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
jvm 1    |  at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1934)

任何形式的幫助表示贊賞。

EDIT1:

這是前端的tpl文件

<div class="label1"><h3 class="label">Host:</h3></div>
     <div class="field1"><input type="text" class="input1" name="host" size="20" value="$HOST$"></div>
         <div class="port"><h3 class="label">Port:</h3></div>
         <div class="fieldport"><input type="text" class="fieldport" name="port" size="5" value="$PORT$"></div>
         <div class="ssl">
                <input type="radio" name="sslEnable" value="$SSLENABLE$">
                    Enable SSL?
         </div>
         <div class="tls">
                <input type="radio" name="tlsEnable" value="$TLSENABLE$">
                    Enable TLS?
         </div>
         <div class="auth">
                <input type="checkbox" name="auth"$AUTH$>
                    Enable Authentication?
         </div>            
     <div class="label2"><h3 class="label">User:</h3></div>
     <div class="field2"><input type="text" class="input1" name="user" size="20" value="$USER$"></div>
     <div class="label3"><h3 class="label">Password:</h3></div>
     <div class="field3"><input type="password" class="input1" name="password" size="20" value="$PASSWORD$"></div>
     <div class="label4"><h3 class="label">Recipient(s):</h3></div>
     <div class="field4"><input type="text" class="input1" name="recipients" size="50" value="$RECIPIENTS$"></div>

值將保存在配置文件中,如下所示:

host=smtp.gmail.com
port=587
ssl=false
tls=true
auth=true
user=send_user_email@gmail.com
password=O0UbYboDfVFRaiA=
recipients=cc_user_email@gmail.com
trigger1=false
attempt=0
trigger2=false
percent=5
anyOrAll=ANY
trigger3=true
format=HTML
trigger4=true
trigger5=true

EDIT2:

public static void sendEmail(String message)
      throws NoSuchProviderException, AddressException, MessagingException
  {
    if (message == null || message.trim().equals("")) return;

    StringBuffer content = new StringBuffer();
    content.append(getHeader());
    content.append(message);
    content.append(getFooter());
    String format = NotifyProps.getFormat();
    String type = "text/plain";
    if (format.equals(NotifyProps.HTML)) type = "text/html";

    sendEmail(NotifyProps.getHost(), NotifyProps.getPort(), Boolean.toString(NotifyProps.getUseAuth()), Boolean.toString(NotifyProps.getUseSSL()), Boolean.toString(NotifyProps.getUseTLS()),NotifyProps.getUser(), NotifyProps.getPassword(),
              "Transaction Processor Auto Notification", content.toString(), type,
              NotifyProps.getRecipients())
  }

這是設置和獲取屬性的類:

https://codeshare.io/5G8ki

謝謝。

你的代碼看起來還不錯,至少有一個大問題。 您正嘗試對TLS和SSL使用相同的端口(587)。 我不確定TLS,但如果您將請求發送到端口465,則SSL代碼應該有效。如此處所寫(google FAQ)

在端口465(使用SSL)和端口587(使用TLS)上配置SMTP服務器[...]

他們有自己的特定端口。 您獲得的SSL錯誤:

Unrecognized SSL message, plaintext connection?

您的客戶端是否了解它收到非SSL編碼響應的事實(由於TLS端口未實現SSL)。

我們為TLS設置了更多屬性

props.put("mail.smtp.starttls.enable", "true");
props.setProperty("mail.smtp.ssl.enable", "true");
props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");

對於Auth使用smtps而不是smtp

props.setProperty("mail.smtps.auth", useAuth);

在獲得運輸時

session.getTransport("smtps"); 

連接時再次傳遞主機電子郵件和密碼

transport.connect("smtp.gmail.com", "user@email", "password");

用於調試

session.setDebug(true);

請嘗試以下適用於我的代碼。

public void sendEmail(){

        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", "465");

Session session = Session.getDefaultInstance(props,
            new javax.mail.Authenticator() {
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication("senderEmail@gmail.com","secret");
                }
            });

            try {
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("from-email@gmail.com"));
            message.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse("to-email@gmail.com"));
            message.setSubject("This is testing message");
            message.setText("Hi this is testing email....not spam");

        Transport.send(message);
            System.out.println("email successfully sent..");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }

最近,gmail中有一個更新安全性。 您必須在https://myaccount.google.com/security?pli=1頁面中選擇“允許安全性較低的應用程序訪問”選項。 然后,您可以毫無問題地從您的帳戶發送郵件

simple-java-mail有一個簡單的枚舉,可用於表示SSL或TLS。 您無需擔心這種方式的正確屬性:

Email email = new Email();

(...)

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帳戶生成應用程序專用密碼才能使此示例正常運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM