ส่งอีเมลโดยใช้ java


112

ฉันพยายามส่งอีเมลโดยใช้ Java:

import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.activation.*;

public class SendEmail {

   public static void main(String [] args) {

      // Recipient's email ID needs to be mentioned.
      String to = "abcd@gmail.com";

      // Sender's email ID needs to be mentioned
      String from = "web@gmail.com";

      // Assuming you are sending email from localhost
      String host = "localhost";

      // Get system properties
      Properties properties = System.getProperties();

      // Setup mail server
      properties.setProperty("mail.smtp.host", host);

      // Get the default Session object.
      Session session = Session.getDefaultInstance(properties);

      try{
         // Create a default MimeMessage object.
         MimeMessage message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.addRecipient(Message.RecipientType.TO,
                                  new InternetAddress(to));

         // Set Subject: header field
         message.setSubject("This is the Subject Line!");

         // Now set the actual message
         message.setText("This is actual message");

         // Send message
         Transport.send(message);
         System.out.println("Sent message successfully....");
      }catch (MessagingException mex) {
         mex.printStackTrace();
      }
   }
}

ฉันได้รับข้อผิดพลาด:

javax.mail.MessagingException: Could not connect to SMTP host: localhost, port: 25;
  nested exception is:java.net.ConnectException: Connection refused: connect
        at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1706)
        at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:525)

รหัสนี้จะใช้ส่งอีเมลได้หรือไม่


11
คุณใช้เซิร์ฟเวอร์ SMTP บนเครื่องเดียวกันที่ฟังบนพอร์ต 25 หรือไม่
Jeff

ฉันจะสมมติตามที่อยู่ของคุณว่าคุณพยายามส่งต่อผ่าน gmail? ถ้าเป็นจริงฉันอาจมีรหัสบางอย่างที่คุณสามารถใช้ได้ นี่คือคำแนะนำคุณต้องใช้ TLS
Paul Gregoire

@ วันจันทร์มันจะมีประโยชน์ถ้าคุณสามารถห้ารหัสได้ ฉันต้องการส่งต่อโดยใช้ gmail
Mohit Bansal

ลิงก์ในคำตอบของฉันด้านล่างสิ่งเดียวที่จับได้คือไม่ได้ใช้ไลบรารี JavaMail ฉันสามารถส่งแหล่งข้อมูลทั้งหมดให้คุณได้หากคุณต้องการ
Paul Gregoire

คำตอบ:


98

รหัสต่อไปนี้ทำงานได้ดีกับเซิร์ฟเวอร์ SMTP ของ Google คุณต้องระบุชื่อผู้ใช้และรหัสผ่าน Google ของคุณ

import com.sun.mail.smtp.SMTPTransport;
import java.security.Security;
import java.util.Date;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 *
 * @author doraemon
 */
public class GoogleMail {
    private GoogleMail() {
    }

    /**
     * Send email using GMail SMTP server.
     *
     * @param username GMail username
     * @param password GMail password
     * @param recipientEmail TO recipient
     * @param title title of the message
     * @param message message to be sent
     * @throws AddressException if the email address parse failed
     * @throws MessagingException if the connection is dead or not in the connected state or if the message is not a MimeMessage
     */
    public static void Send(final String username, final String password, String recipientEmail, String title, String message) throws AddressException, MessagingException {
        GoogleMail.Send(username, password, recipientEmail, "", title, message);
    }

    /**
     * Send email using GMail SMTP server.
     *
     * @param username GMail username
     * @param password GMail password
     * @param recipientEmail TO recipient
     * @param ccEmail CC recipient. Can be empty if there is no CC recipient
     * @param title title of the message
     * @param message message to be sent
     * @throws AddressException if the email address parse failed
     * @throws MessagingException if the connection is dead or not in the connected state or if the message is not a MimeMessage
     */
    public static void Send(final String username, final String password, String recipientEmail, String ccEmail, String title, String message) throws AddressException, MessagingException {
        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";

        // Get a Properties object
        Properties props = System.getProperties();
        props.setProperty("mail.smtps.host", "smtp.gmail.com");
        props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        props.setProperty("mail.smtp.port", "465");
        props.setProperty("mail.smtp.socketFactory.port", "465");
        props.setProperty("mail.smtps.auth", "true");

        /*
        If set to false, the QUIT command is sent and the connection is immediately closed. If set 
        to true (the default), causes the transport to wait for the response to the QUIT command.

        ref :   http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package-summary.html
                http://forum.java.sun.com/thread.jspa?threadID=5205249
                smtpsend.java - demo program from javamail
        */
        props.put("mail.smtps.quitwait", "false");

        Session session = Session.getInstance(props, null);

        // -- Create a new message --
        final MimeMessage msg = new MimeMessage(session);

        // -- Set the FROM and TO fields --
        msg.setFrom(new InternetAddress(username + "@gmail.com"));
        msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipientEmail, false));

        if (ccEmail.length() > 0) {
            msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(ccEmail, false));
        }

        msg.setSubject(title);
        msg.setText(message, "utf-8");
        msg.setSentDate(new Date());

        SMTPTransport t = (SMTPTransport)session.getTransport("smtps");

        t.connect("smtp.gmail.com", username, password);
        t.sendMessage(msg, msg.getAllRecipients());      
        t.close();
    }
}

อัปเดตเมื่อ 11 ธันวาคม 2558

ชื่อผู้ใช้ + รหัสผ่านไม่ใช่ทางออกที่แนะนำอีกต่อไป ทั้งนี้เนื่องจาก

ฉันลองแล้ว Gmail ได้ส่งอีเมลที่ใช้เป็นชื่อผู้ใช้ในรหัสนี้โดยแจ้งว่าเราเพิ่งบล็อกการพยายามลงชื่อเข้าใช้บัญชี Google ของคุณและนำฉันไปที่หน้าการสนับสนุนนี้: support.google.com/accounts/answer/6010255 ดังนั้นจึงดูเหมือนว่าจะใช้งานได้บัญชีอีเมลที่ใช้ส่งจำเป็นต้องลดความปลอดภัยของตัวเอง

Google ปล่อย Gmail API - https://developers.google.com/gmail/api/?hl=en เราควรใช้เมธอด oAuth2 แทน username + password

นี่คือข้อมูลโค้ดสำหรับใช้งานกับ Gmail API

GoogleMail.java

import com.google.api.client.util.Base64;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.model.Message;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Properties;

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

/**
 *
 * @author doraemon
 */
public class GoogleMail {
    private GoogleMail() {
    }

    private static MimeMessage createEmail(String to, String cc, String from, String subject, String bodyText) throws MessagingException {
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);

        MimeMessage email = new MimeMessage(session);
        InternetAddress tAddress = new InternetAddress(to);
        InternetAddress cAddress = cc.isEmpty() ? null : new InternetAddress(cc);
        InternetAddress fAddress = new InternetAddress(from);

        email.setFrom(fAddress);
        if (cAddress != null) {
            email.addRecipient(javax.mail.Message.RecipientType.CC, cAddress);
        }
        email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress);
        email.setSubject(subject);
        email.setText(bodyText);
        return email;
    }

    private static Message createMessageWithEmail(MimeMessage email) throws MessagingException, IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        email.writeTo(baos);
        String encodedEmail = Base64.encodeBase64URLSafeString(baos.toByteArray());
        Message message = new Message();
        message.setRaw(encodedEmail);
        return message;
    }

    public static void Send(Gmail service, String recipientEmail, String ccEmail, String fromEmail, String title, String message) throws IOException, MessagingException {
        Message m = createMessageWithEmail(createEmail(recipientEmail, ccEmail, fromEmail, title, message));
        service.users().messages().send("me", m).execute();
    }
}

หากต้องการสร้างบริการ Gmail ที่ได้รับอนุญาตผ่าน oAuth2 นี่คือข้อมูลโค้ด

Utils.java

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.oauth2.Oauth2;
import com.google.api.services.oauth2.model.Userinfoplus;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.yccheok.jstock.engine.Pair;

/**
 *
 * @author yccheok
 */
public class Utils {
    /** Global instance of the JSON factory. */
    private static final GsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

    /** Global instance of the HTTP transport. */
    private static HttpTransport httpTransport;

    private static final Log log = LogFactory.getLog(Utils.class);

    static {
        try {
            // initialize the transport
            httpTransport = GoogleNetHttpTransport.newTrustedTransport();

        } catch (IOException ex) {
            log.error(null, ex);
        } catch (GeneralSecurityException ex) {
            log.error(null, ex);
        }
    }

    private static File getGmailDataDirectory() {
        return new File(org.yccheok.jstock.gui.Utils.getUserDataDirectory() + "authentication" + File.separator + "gmail");
    }

    /**
     * Send a request to the UserInfo API to retrieve the user's information.
     *
     * @param credentials OAuth 2.0 credentials to authorize the request.
     * @return User's information.
     * @throws java.io.IOException
     */
    public static Userinfoplus getUserInfo(Credential credentials) throws IOException
    {
        Oauth2 userInfoService =
            new Oauth2.Builder(httpTransport, JSON_FACTORY, credentials).setApplicationName("JStock").build();
        Userinfoplus userInfo  = userInfoService.userinfo().get().execute();
        return userInfo;
    }

    public static String loadEmail(File dataStoreDirectory)  {
        File file = new File(dataStoreDirectory, "email");
        try {
            return new String(Files.readAllBytes(Paths.get(file.toURI())), "UTF-8");
        } catch (IOException ex) {
            log.error(null, ex);
            return null;
        }
    }

    public static boolean saveEmail(File dataStoreDirectory, String email) {
        File file = new File(dataStoreDirectory, "email");
        try {
            //If the constructor throws an exception, the finally block will NOT execute
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
            try {
                writer.write(email);
            } finally {
                writer.close();
            }
            return true;
        } catch (IOException ex){
            log.error(null, ex);
            return false;
        }
    }

    public static void logoutGmail() {
        File credential = new File(getGmailDataDirectory(), "StoredCredential");
        File email = new File(getGmailDataDirectory(), "email");
        credential.delete();
        email.delete();
    }

    public static Pair<Pair<Credential, String>, Boolean> authorizeGmail() throws Exception {
        // Ask for only the permissions you need. Asking for more permissions will
        // reduce the number of users who finish the process for giving you access
        // to their accounts. It will also increase the amount of effort you will
        // have to spend explaining to users what you are doing with their data.
        // Here we are listing all of the available scopes. You should remove scopes
        // that you are not actually using.
        Set<String> scopes = new HashSet<>();

        // We would like to display what email this credential associated to.
        scopes.add("email");

        scopes.add(GmailScopes.GMAIL_SEND);

        // load client secrets
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(Utils.JSON_FACTORY,
            new InputStreamReader(Utils.class.getResourceAsStream("/assets/authentication/gmail/client_secrets.json")));

        return authorize(clientSecrets, scopes, getGmailDataDirectory());
    }

    /** Authorizes the installed application to access user's protected data.
     * @return 
     * @throws java.lang.Exception */
    private static Pair<Pair<Credential, String>, Boolean> authorize(GoogleClientSecrets clientSecrets, Set<String> scopes, File dataStoreDirectory) throws Exception {
        // Set up authorization code flow.

        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            httpTransport, JSON_FACTORY, clientSecrets, scopes)
            .setDataStoreFactory(new FileDataStoreFactory(dataStoreDirectory))
            .build();
        // authorize
        return new MyAuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
    }

    public static Gmail getGmail(Credential credential) {
        Gmail service = new Gmail.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName("JStock").build();
        return service;        
    }
}

เพื่อมอบวิธีการพิสูจน์ตัวตน oAuth2 ที่เป็นมิตรกับผู้ใช้ฉันจึงใช้ JavaFX เพื่อแสดงกล่องโต้ตอบอินพุตต่อไปนี้

ใส่คำอธิบายภาพที่นี่

กุญแจสำคัญในการแสดงกล่องโต้ตอบ oAuth2 ที่เป็นมิตรกับผู้ใช้สามารถพบได้ในMyAuthorizationCodeInstalledApp.javaและSimpleSwingBrowser.java


รับข้อผิดพลาด: ข้อยกเว้นในเธรด "หลัก" javax.mail.MessagingException: ไม่สามารถเชื่อมต่อกับโฮสต์ SMTP: smtp.gmail.com, พอร์ต: 465; ข้อยกเว้นที่ซ้อนกันคือ: java.net.ConnectException: การเชื่อมต่อหมดเวลา: เชื่อมต่อที่ com.sun.mail.smtp.SMTPTransport.openServer (SMTPTransport.java:1706)
Mohit Bansal

1
หากคุณ ping smtp.gmail.com คุณได้รับการตอบกลับหรือไม่
Cheok Yan Cheng

อย่างที่บอกว่าก่อนหน้านี้ฉันยังใหม่กับ STMP และฉันไม่รู้วิธี ping smtp.gmail.com
Mohit Bansal

2
ในพรอมต์คำสั่งพิมพ์ "ping smtp.gmail.com" แล้วกด Enter
Cheok Yan Cheng

12
ฉันไม่ชอบที่เมธอดถูกเรียกSendแทนsendแต่มันเป็นคลาสที่มีประโยชน์ มีความคิดเห็นเกี่ยวกับผลกระทบด้านความปลอดภัยของการจัดเก็บรหัสผ่าน gmail ในรหัสหรือไม่?
Simon Forsberg

48

รหัสต่อไปนี้ใช้ได้ผลสำหรับฉัน

import java.io.UnsupportedEncodingException;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
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 SendMail {

    public static void main(String[] args) {

        final String username = "your_user_name@gmail.com";
        final String password = "yourpassword";

        Properties props = new Properties();
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.port", "587");

        Session session = Session.getInstance(props,
          new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(username, password);
            }
          });

        try {

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("your_user_name@gmail.com"));
            message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("to_email_address@domain.com"));
            message.setSubject("Testing Subject");
            message.setText("Dear Mail Crawler,"
                + "\n\n No spam to my email, please!");

            Transport.send(message);

            System.out.println("Done");

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

1
ทำงานกับบัญชีที่ปิดใช้งานการรับรองความถูกต้อง 2 ปัจจัย โซลูชันนี้ยอดเยี่ยมเนื่องจากเป็นแพ็คเกจในพื้นที่และไม่จำเป็นต้องใช้แพ็คเกจซัน
AlikElzin-kilaka

ในการใช้รหัสนี้อีเมลที่จะส่งต้องเป็นบัญชี gmail หรือไม่?
Erick

3
รหัสได้ผลสำหรับฉัน แต่ก่อนอื่นฉันต้องทำสิ่ง นี้และเปิด "การเข้าถึงสำหรับแอปที่มีความปลอดภัยน้อย"

@ user4966430 เห็นด้วย! และขอบคุณ!
raikumardipak

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

import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;


public class SendEmail extends Object{

public static void main(String [] args)
{

    try{

        Properties props = new Properties();
        props.put("mail.smtp.host", "smtp.mail.yahoo.com"); // for gmail use smtp.gmail.com
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "true"); 
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.port", "465");
        props.put("mail.smtp.socketFactory.port", "465");
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");

        Session mailSession = Session.getInstance(props, new javax.mail.Authenticator() {

            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("username@yahoo.com", "password");
            }
        });

        mailSession.setDebug(true); // Enable the debug mode

        Message msg = new MimeMessage( mailSession );

        //--[ Set the FROM, TO, DATE and SUBJECT fields
        msg.setFrom( new InternetAddress( "fromusername@yahoo.com" ) );
        msg.setRecipients( Message.RecipientType.TO,InternetAddress.parse("tousername@gmail.com") );
        msg.setSentDate( new Date());
        msg.setSubject( "Hello World!" );

        //--[ Create the body of the mail
        msg.setText( "Hello from my first e-mail sent with JavaMail" );

        //--[ Ask the Transport class to send our mail message
        Transport.send( msg );

    }catch(Exception E){
        System.out.println( "Oops something has gone pearshaped!");
        System.out.println( E );
    }
}
}

ไฟล์ jar ที่จำเป็น

คลิกที่นี่ - วิธีเพิ่ม External Jars


11

คำตอบสั้น ๆ - ไม่

คำตอบแบบยาว - ไม่เนื่องจากรหัสขึ้นอยู่กับการมีอยู่ของเซิร์ฟเวอร์ SMTP ที่ทำงานบนเครื่องโลคัลและการฟังบนพอร์ต 25 เซิร์ฟเวอร์ SMTP (ในทางเทคนิคคือ MTA หรือ Mail Transfer Agent) มีหน้าที่ในการสื่อสารกับ Mail User Agent (MUA ซึ่งในกรณีนี้คือกระบวนการ Java) เพื่อรับอีเมลขาออก

ปัจจุบัน MTA มักมีหน้าที่รับอีเมลจากผู้ใช้สำหรับโดเมนหนึ่ง ๆ ดังนั้นสำหรับโดเมน gmail.com นั้นจะเป็นเซิร์ฟเวอร์อีเมลของ Google ที่รับผิดชอบในการตรวจสอบตัวแทนผู้ใช้อีเมลและด้วยเหตุนี้จึงโอนอีเมลไปยังกล่องจดหมายบนเซิร์ฟเวอร์ GMail ฉันไม่แน่ใจว่า GMail เชื่อถือเซิร์ฟเวอร์การส่งต่ออีเมลแบบเปิดหรือไม่ แต่ไม่ใช่เรื่องง่ายที่จะดำเนินการตรวจสอบสิทธิ์ในนามของ Google จากนั้นจึงส่งต่ออีเมลไปยังเซิร์ฟเวอร์ GMail

หากคุณอ่านคำถามที่พบบ่อยเกี่ยวกับ JavaMail เกี่ยวกับการใช้ JavaMail เพื่อเข้าถึง GMailคุณจะสังเกตเห็นว่าชื่อโฮสต์และพอร์ตนั้นชี้ไปที่เซิร์ฟเวอร์ GMail และไม่ใช่ localhost อย่างแน่นอน หากคุณตั้งใจจะใช้เครื่องในพื้นที่ของคุณคุณจะต้องดำเนินการส่งต่อหรือส่งต่อ

คุณอาจต้องเข้าใจโปรโตคอล SMTP ในเชิงลึกหากคุณตั้งใจจะไปที่ไหนก็ได้เมื่อพูดถึง SMTP คุณสามารถเริ่มต้นด้วยบทความ Wikipedia เกี่ยวกับ SMTPแต่ความคืบหน้าเพิ่มเติมจะทำให้ต้องเขียนโปรแกรมกับเซิร์ฟเวอร์ SMTP


ฉันสามารถใช้ Tomcat เป็นเซิร์ฟเวอร์ SMTP ได้หรือไม่ ความช่วยเหลือในเรื่องเดียวกันจะได้รับการชื่นชม :)
CᴴᴀZ

3
@ChaZ ได้แนวคิดมาจากไหนว่า Tomcat จะเป็นเซิร์ฟเวอร์ SMTP?
eis

6

คุณต้องมีเซิร์ฟเวอร์ SMTP สำหรับส่งอีเมล มีเซิร์ฟเวอร์ที่คุณสามารถติดตั้งภายในเครื่องพีซีของคุณเองหรือคุณสามารถใช้เซิร์ฟเวอร์ออนไลน์หลายเครื่องก็ได้ หนึ่งในเซิร์ฟเวอร์ที่รู้จักกันดีคือของ Google:

ฉันเพิ่งทดสอบการกำหนดค่า SMTP ของ Google ที่อนุญาตสำเร็จโดยใช้ตัวอย่างแรกจากSimple Java Mail :

    final Email email = EmailBuilder.startingBlank()
        .from("lollypop", "lol.pop@somemail.com")
        .to("C.Cane", "candycane@candyshop.org")
        .withPlainText("We should meet up!")
        .withHTMLText("<b>We should meet up!</b>")
        .withSubject("hey");

    // starting 5.0.0 do the following using the MailerBuilder instead...
    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 ต้องการ TLS ในพอร์ต 25 เช่นกันแม้ว่าคำแนะนำของ Google จะบอกเป็นอย่างอื่นก็ตาม


1
ตามชื่อก็บอกง่ายๆ
Kai Wang

4

ผ่านมาแล้วพอสมควรแล้วที่โพสต์นี้ แต่ ณ วันที่ 13 พฤศจิกายน 2555 ฉันสามารถตรวจสอบได้ว่าพอร์ต 465 ยังใช้งานได้

อ้างอิงคำตอบของ GaryM ในฟอรัมนี้ ฉันหวังว่านี่จะช่วยคนได้อีกไม่กี่คน

/*
* Created on Feb 21, 2005
*
*/

import java.security.Security;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class GoogleTest {

    private static final String SMTP_HOST_NAME = "smtp.gmail.com";
    private static final String SMTP_PORT = "465";
    private static final String emailMsgTxt = "Test Message Contents";
    private static final String emailSubjectTxt = "A test from gmail";
    private static final String emailFromAddress = "";
    private static final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
    private static final String[] sendTo = { "" };


    public static void main(String args[]) throws Exception {

        Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());

        new GoogleTest().sendSSLMessage(sendTo, emailSubjectTxt,
            emailMsgTxt, emailFromAddress);
        System.out.println("Sucessfully mail to All Users");
    }

    public void sendSSLMessage(String recipients[], String subject,
                               String message, String from) throws MessagingException {
        boolean debug = true;

        Properties props = new Properties();
        props.put("mail.smtp.host", SMTP_HOST_NAME);
        props.put("mail.smtp.auth", "true");
        props.put("mail.debug", "true");
        props.put("mail.smtp.port", SMTP_PORT);
        props.put("mail.smtp.socketFactory.port", SMTP_PORT);
        props.put("mail.smtp.socketFactory.class", SSL_FACTORY);
        props.put("mail.smtp.socketFactory.fallback", "false");

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

        session.setDebug(debug);

        Message msg = new MimeMessage(session);
        InternetAddress addressFrom = new InternetAddress(from);
        msg.setFrom(addressFrom);

        InternetAddress[] addressTo = new InternetAddress[recipients.length];
        for (int i = 0; i < recipients.length; i++) {
            addressTo[i] = new InternetAddress(recipients);
        }
        msg.setRecipients(Message.RecipientType.TO, addressTo);

        // Setting the Subject and Content Type
        msg.setSubject(subject);
        msg.setContent(message, "text/plain");
        Transport.send(msg);
    }
}

1
แม้ว่าลิงก์นี้อาจตอบคำถามได้ แต่ควรรวมส่วนสำคัญของคำตอบไว้ที่นี่และระบุลิงก์เพื่อการอ้างอิง คำตอบแบบลิงก์เท่านั้นอาจไม่ถูกต้องหากหน้าที่เชื่อมโยงเปลี่ยนไป - จากรีวิว
swiftBoy

1
เพิ่มคำตอบจากโพสต์
Mukus

1
@ มูกัชกึ๊ด !! ที่จะช่วยใครบางคนในอนาคต
swiftBoy

3

รหัสต่อไปนี้ใช้งานได้ดีลองใช้เป็นแอปพลิเคชัน java กับ javamail-1.4.5.jar

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public class MailSender
{
    final String senderEmailID = "typesendermailid@gmail.com";
    final String senderPassword = "typesenderpassword";
    final String emailSMTPserver = "smtp.gmail.com";
    final String emailServerPort = "465";
    String receiverEmailID = null;
    static String emailSubject = "Test Mail";
    static String emailBody = ":)";

    public MailSender(
            String receiverEmailID,
            String emailSubject,
            String emailBody
    ) {
        this.receiverEmailID=receiverEmailID;
        this.emailSubject=emailSubject;
        this.emailBody=emailBody;
        Properties props = new Properties();
        props.put("mail.smtp.user",senderEmailID);
        props.put("mail.smtp.host", emailSMTPserver);
        props.put("mail.smtp.port", emailServerPort);
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.socketFactory.port", emailServerPort);
        props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
        props.put("mail.smtp.socketFactory.fallback", "false");
        SecurityManager security = System.getSecurityManager();
        try {
            Authenticator auth = new SMTPAuthenticator();
            Session session = Session.getInstance(props, auth);
            MimeMessage msg = new MimeMessage(session);
            msg.setText(emailBody);
            msg.setSubject(emailSubject);
            msg.setFrom(new InternetAddress(senderEmailID));
            msg.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(receiverEmailID));
            Transport.send(msg);
            System.out.println("Message send Successfully:)");
        }
        catch (Exception mex)
        {
            mex.printStackTrace();
        }
    }

    public class SMTPAuthenticator extends javax.mail.Authenticator
    {
        public PasswordAuthentication getPasswordAuthentication()
        {
            return new PasswordAuthentication(senderEmailID, senderPassword);
        }
    }

    public static void main(String[] args)
    {
        MailSender mailSender=new
            MailSender("typereceivermailid@gmail.com",emailSubject,emailBody);
    }
}

2

รหัสนี้จะใช้ส่งอีเมลได้หรือไม่

ไม่ไม่ไม่เปลี่ยนบางส่วนเนื่องจากคุณได้รับข้อผิดพลาด ขณะนี้คุณกำลังพยายามส่งอีเมลผ่านเซิร์ฟเวอร์ SMTP ที่ทำงานบน localhost แต่คุณไม่ได้ใช้งานไฟล์ConnectException.

สมมติว่ารหัสนั้นใช้ได้ (ฉันไม่ได้ตรวจสอบจริงๆ) คุณจะต้องเรียกใช้เซิร์ฟเวอร์ SMTP ในเครื่องหรือใช้ (ระยะไกล) (จาก ISP ของคุณ)

เกี่ยวกับโค้ดคุณสามารถค้นหาตัวอย่างได้ในแพ็คเกจดาวน์โหลด JavaMail ตามที่กล่าวไว้ในคำถามที่พบบ่อย :

ฉันจะหาโปรแกรมตัวอย่างที่แสดงวิธีการใช้ JavaMail ได้ที่ไหน?

ถาม: ฉันจะหาโปรแกรมตัวอย่างที่แสดงวิธีใช้ JavaMail ได้ที่ไหน
ตอบ: มีโปรแกรมตัวอย่างมากมายที่รวมอยู่ในแพ็คเกจดาวน์โหลด JavaMailซึ่งรวมถึงโปรแกรมบรรทัดคำสั่งง่ายๆที่แสดงลักษณะต่างๆของ JavaMail API แอปพลิเคชัน GUI ที่ใช้ Swing แอปพลิเคชันที่ใช้ servlet แบบง่ายและเว็บแอปพลิเคชันที่สมบูรณ์โดยใช้หน้า JSP และ ไลบรารีแท็ก


สวัสดีเซิร์ฟเวอร์ smtp คืออะไร? รวมและรวมอยู่ในเซิร์ฟเวอร์อีเมลหรือไม่ หรือเราต้องตั้งค่า smtp แยกกัน?
GMsoF

dovecot เป็นเซิร์ฟเวอร์ SMTP ถามตัวเองคำถามนี้: สิ่งที่ซอฟต์แวร์ Google ไม่วิ่งที่คุณส่งอีเมลนี้เพื่อ ? พวกเขากำลังเรียกใช้เซิร์ฟเวอร์ smtp บางประเภท Dovecot เป็นสิ่งที่ดี dovecot และ postfix ร่วมกันจะดีกว่า ฉันคิดว่า postfix เป็นส่วน smtp และ dovecot ส่วน imap
Thufir

2

ลองดูสิ มันทำงานได้ดีสำหรับฉัน ตรวจสอบให้แน่ใจว่าก่อนส่งอีเมลคุณต้องให้สิทธิ์การเข้าถึงแอปที่มีความปลอดภัยน้อยในบัญชี Gmail ของคุณ ไปที่ลิงค์ต่อไปนี้และลองใช้รหัส java นี้
เปิดใช้งาน gmail สำหรับแอปที่มีความปลอดภัยน้อย

คุณต้องนำเข้าไฟล์ javax.mail.jar และไฟล์ activation.jar ไปยังโปรเจ็กต์ของคุณ

นี่คือรหัสเต็มสำหรับส่งอีเมลใน java

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public class SendEmail {

    final String senderEmail = "your email address";
    final String senderPassword = "your password";
    final String emailSMTPserver = "smtp.gmail.com";
    final String emailServerPort = "587";
    String receiverEmail = null;
    String emailSubject = null;
    String emailBody = null;

    public SendEmail(String receiverEmail, String Subject, String message) {
        this.receiverEmail = receiverEmail;
        this.emailSubject = Subject;
        this.emailBody = message;

        Properties props = new Properties();
        props.put("mail.smtp.user", senderEmail);
        props.put("mail.smtp.host", emailSMTPserver);
        props.put("mail.smtp.port", emailServerPort);
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.socketFactory.port", emailServerPort);
        props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");

        SecurityManager security = System.getSecurityManager();

        try {
            Authenticator auth = new SMTPAuthenticator();
            Session session = Session.getInstance(props, auth);

            Message msg = new MimeMessage(session);
            msg.setText(emailBody);
            msg.setSubject(emailSubject);
            msg.setFrom(new InternetAddress(senderEmail));
            msg.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(receiverEmail));
            Transport.send(msg);
            System.out.println("send successfully");
        } catch (Exception ex) {
            System.err.println("Error occurred while sending.!");
        }

    }

    private class SMTPAuthenticator extends javax.mail.Authenticator {

        public PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(senderEmail, senderPassword);
        }
    }

    public static void main(String[] args) {
        SendEmail send = new SendEmail("receiver email address", "subject", "message");
    }

}

2

นี่คือวิธีแก้ปัญหาที่ใช้งานได้ครับ มันรับประกัน

  1. ก่อนอื่นให้เปิดบัญชี gmail ของคุณที่คุณต้องการส่งอีเมลเช่นในกรณีของคุณ xyz@gmail.com
  2. เปิดลิงค์ด้านล่างนี้:

    https://support.google.com/accounts/answer/6010255?hl=en

  3. คลิกที่ "ไปที่ส่วน" แอปที่มีความปลอดภัยน้อย "ในบัญชีของฉัน" ตัวเลือก
  4. จากนั้นเปิดเครื่อง
  5. แค่นั้นแหละ (:

นี่คือรหัสของฉัน:

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

public class SendEmail {

   final String senderEmailID = "Sender Email id";
final String senderPassword = "Sender Pass word";
final String emailSMTPserver = "smtp.gmail.com";
final String emailServerPort = "465";
String receiverEmailID = null;
static String emailSubject = "Test Mail";
static String emailBody = ":)";
public SendEmail(String receiverEmailID, String emailSubject, String emailBody)
{
this.receiverEmailID=receiverEmailID;
this.emailSubject=emailSubject;
this.emailBody=emailBody;
Properties props = new Properties();
props.put("mail.smtp.user",senderEmailID);
props.put("mail.smtp.host", emailSMTPserver);
props.put("mail.smtp.port", emailServerPort);
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.socketFactory.port", emailServerPort);
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.socketFactory.fallback", "false");
SecurityManager security = System.getSecurityManager();
try
{
Authenticator auth = new SMTPAuthenticator();
Session session = Session.getInstance(props, auth);
MimeMessage msg = new MimeMessage(session);
msg.setText(emailBody);
msg.setSubject(emailSubject);
msg.setFrom(new InternetAddress(senderEmailID));
msg.addRecipient(Message.RecipientType.TO,
new InternetAddress(receiverEmailID));
Transport.send(msg);
System.out.println("Message send Successfully:)");
}
catch (Exception mex)
{
mex.printStackTrace();
}
}
public class SMTPAuthenticator extends javax.mail.Authenticator
{
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(senderEmailID, senderPassword);
}
}
    public static void main(String[] args) {
       SendEmail mailSender;
        mailSender = new SendEmail("Receiver Email id","Testing Code 2 example","Testing Code Body yess");
    }

}

ขอบคุณ! มันได้ผลสำหรับฉัน! ฉันไปที่ตัวเลือก "แอปที่มีความปลอดภัยน้อย" ในบัญชีของฉัน "และสร้างรหัสผ่านเพื่อให้แอปของฉันใช้
raikumardipak

1

ฉันได้เพิ่มคลาส gmail java ที่ใช้งานได้บน pastebin เพื่อให้คุณตรวจสอบโปรดให้ความสนใจเป็นพิเศษกับเมธอด "startSessionWithTLS" และคุณอาจสามารถปรับ JavaMail เพื่อให้มีฟังก์ชันการทำงานเหมือนกัน http://pastebin.com/VE8Mqkqp


บางทีคุณอาจให้คำตอบเพิ่มเติมอีกเล็กน้อยได้เช่นกัน?
Antti Haapala

1

รหัสของคุณใช้งานได้นอกเหนือจากการตั้งค่าการเชื่อมต่อกับเซิร์ฟเวอร์ SMTP คุณต้องใช้เซิร์ฟเวอร์เมล (SMTP) เพื่อส่งอีเมลให้คุณ

นี่คือรหัสที่คุณแก้ไข ฉันแสดงความคิดเห็นเกี่ยวกับส่วนที่ไม่จำเป็นและเปลี่ยนการสร้างเซสชันดังนั้นจึงต้องใช้ Authenticator ตอนนี้เพียงแค่ค้นหา SMPT_HOSTNAME, USERNAME และ PASSWORD ที่คุณต้องการใช้ (โดยปกติผู้ให้บริการอินเทอร์เน็ตของคุณจะมีให้)

ฉันมักจะทำแบบนี้เสมอ (โดยใช้เซิร์ฟเวอร์ SMTP ระยะไกลที่ฉันรู้จัก) เนื่องจากการเรียกใช้เซิร์ฟเวอร์อีเมลในพื้นที่ไม่ใช่เรื่องเล็กน้อยใน Windows (เห็นได้ชัดว่าค่อนข้างง่ายภายใต้ Linux)

import java.util.*;

import javax.mail.*;
import javax.mail.internet.*;

//import javax.activation.*;

public class SendEmail {

    private static String SMPT_HOSTNAME = "";
    private static String USERNAME = "";
    private static String PASSWORD = "";

    public static void main(String[] args) {

        // Recipient's email ID needs to be mentioned.
        String to = "abcd@gmail.com";

        // Sender's email ID needs to be mentioned
        String from = "web@gmail.com";

        // Assuming you are sending email from localhost
        // String host = "localhost";

        // Get system properties
        Properties properties = System.getProperties();

        // Setup mail server
        properties.setProperty("mail.smtp.host", SMPT_HOSTNAME);

        // Get the default Session object.
        // Session session = Session.getDefaultInstance(properties);

        // create a session with an Authenticator
        Session session = Session.getInstance(properties, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(USERNAME, PASSWORD);
            }
        });

        try {
            // Create a default MimeMessage object.
            MimeMessage message = new MimeMessage(session);

            // Set From: header field of the header.
            message.setFrom(new InternetAddress(from));

            // Set To: header field of the header.
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(
                    to));

            // Set Subject: header field
            message.setSubject("This is the Subject Line!");

            // Now set the actual message
            message.setText("This is actual message");

            // Send message
            Transport.send(message);
            System.out.println("Sent message successfully....");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }
    }
}

1

465 ใช้งานได้จริงและข้อยกเว้นที่คุณได้รับอาจเกิดจากการยกเลิกการเปิดพอร์ต SMTP 25 โดยค่าเริ่มต้นหมายเลขพอร์ตคือ 25 แต่คุณสามารถกำหนดค่าได้โดยใช้เมลเอเจนต์ที่พร้อมใช้งานเป็นโอเพนซอร์ส - Mercury

เพื่อความเรียบง่ายเพียงใช้การกำหนดค่าต่อไปนี้แล้วคุณจะสบายดี

// Setup your mail server
props.put("mail.smtp.host", SMTP_HOST); 
props.put("mail.smtp.user",FROM_NAME);
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.port", "25");
props.put("mail.debug", "true");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable","true");
props.put("mail.smtp.EnableSSL.enable","true");
props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");  
props.setProperty("mail.smtp.socketFactory.fallback", "false");  
props.setProperty("mail.smtp.port", "465");  
props.setProperty("mail.smtp.socketFactory.port", "465");

หากต้องการข้อมูลเพิ่มเติม: ดูตัวอย่างการทำงานที่สมบูรณ์ตั้งแต่เริ่มต้นที่นี่


1

ฉันได้รับข้อยกเว้นเช่นเดียวกับคุณ สาเหตุคือไม่มีเซิร์ฟเวอร์ smpt ในเครื่องของคุณ (เนื่องจากโฮสต์ของคุณเป็น localhost) หากคุณใช้ windows 7 จะไม่มีเซิร์ฟเวอร์ SMTP ดังนั้นคุณจะต้องดาวน์โหลดติดตั้งและกำหนดค่ากับโดเมนและสร้างบัญชีฉันใช้ hmailserver เป็นเซิร์ฟเวอร์ smtp ที่ติดตั้งและกำหนดค่าในเครื่องภายในของฉัน https://www.hmailserver.com/download


-2

คุณสามารถค้นหาคลาส java ที่สมบูรณ์และเรียบง่ายสำหรับการส่งอีเมลโดยใช้บัญชี Google (gmail) ที่นี่

ส่งอีเมลโดยใช้ java และบัญชี Google

ใช้คุณสมบัติดังต่อไปนี้

Properties props = new Properties();
  props.put("mail.smtp.auth", "true");
  props.put("mail.smtp.starttls.enable", "true");
  props.put("mail.smtp.host", "smtp.gmail.com");
  props.put("mail.smtp.port", "587");

1
โปรดทราบว่าคำตอบแบบลิงก์เท่านั้นไม่สนับสนุนใน SO รวมคำตอบไว้ในคำตอบเองจะดีกว่า
laalto
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.