2015年4月18日 星期六

[Java]以Java發送E-mail

Java 要寄送E-mail,需要透過JavaMail以及JavaBeans Activation Framework (JAF) 。

JAF的用途主要是用來識別檔案的類型。

首先到http://www.oracle.com/technetwork/java/index-138643.html

下載JavaMail ,除非你使用的是Java 1.6以前的版本,否則JAF己內建於Java 1.6中了。

如果你使用的一般非gmail的SMTP伺服器,gmail有啟用SSL,之後再補另一篇來紀錄。


一開始先寄一封純文字的信件,主要寄信程式碼:


 
package javaemail;

import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

/**
 *
 * @author flowercatswets
 */
public class JavaEmail {

    public static void main(String[] args) {

        //user
        String user = "username";
        //password
        String pwd = "abcd1234";

        //接收者的email.
        String to = "abcd@yahoo.com.tw";

        //寄件人的email
        String from = "aa@taida.com.tw";

        // 寄件的smtp伺服器
        String host = "mail.taida.com.tw";

        // 主旨
        String subject = "Java 寄來的信";

        //內文
        String body = "Java程式發送出來的信";

        // 建立一個Properties來設定Properties
        Properties properties = System.getProperties();

        //設定傳輸協定為smtp
        properties.setProperty("mail.transport.protocol", "smtp");
        //設定mail Server
        properties.setProperty("mail.smtp.host", host);
        properties.setProperty("mail.smtp.port", "25");
        //需要驗證帳號密碼
        properties.put("mail.smtp.auth", "true");
        //Bypass the SSL authentication
        properties.put("mail.smtp.ssl.enable", false);
        properties.put("mail.smtp.starttls.enable", false);

        //帳號,密碼
        SmtpAuthenticator authentication = 
                new SmtpAuthenticator(user, pwd);

        // 建立一個Session物件,並把properties傳進去
        Session mailSession = Session.
                getDefaultInstance(properties, authentication);

        try {
            //建立一個 MimeMessage object.
            MimeMessage message = new MimeMessage(mailSession);

            // 設定寄件人
            message.setFrom(new InternetAddress(from));

            // 設定收件人
            message.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(to));

            // 設定主旨
            message.setSubject(subject);

            //設定內文
            message.setText(body);

            Transport transport = mailSession.getTransport();

            // 傳送信件         
            transport.send(message);

            System.out.println("發送成功");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }
    }

}

接下來是認證帳號密碼用的class ,它是繼承Authenticator,

覆寫其中的getPasswordAuthentication,使其可傳回具有帳密碼的

PasswordAuthentication物件
 
package javaemail;

import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;

/**
 *
 * @author flowercatswets
 */
public class SmtpAuthenticator extends Authenticator {

    private String USER;
    private String PASSWORD;

    //空的建構子
    public SmtpAuthenticator() {

        super();
    }

    //可以讓外部傳送帳號密碼進來的建構子
    public SmtpAuthenticator(String user, String password) {
        this();
        this.USER = user;
        this.PASSWORD = password;
    }

    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
        String username = USER;
        String password = PASSWORD;
        if ((username != null) && (username.length() > 0)
                && (password != null)
                && (password.length() > 0)) {

            return new PasswordAuthentication(username, password);
        }

        return null;
    }

}


來看一下執行結果
 


接下來來附加檔案 ,差異只在寄信的主程式

package javaemail;

import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

/**
 *
 * @author flowercatswets
 */
public class JavaEmail {

    public static void main(String[] args) {

        //user
        String user = "username";
        //password
        String pwd = "abcd1234";

        //接收者的email.
        String to = "abcd@yahoo.com.tw";

        //寄件人的email
        String from = "aa@taida.com.tw";

        // 寄件的smtp伺服器
        String host = "mail.taida.com.tw";

        // 主旨
        String subject = "Java 寄來的信";

        //內文
        String body = "Java程式發送出來的信";

        // 建立一個Properties來設定Properties
        Properties properties = System.getProperties();

        //設定傳輸協定為smtp
        properties.setProperty("mail.transport.protocol", "smtp");
        //設定mail Server
        properties.setProperty("mail.smtp.host", host);
        properties.setProperty("mail.smtp.port", "25");
        //需要驗證帳號密碼
        properties.put("mail.smtp.auth", "true");
        //Bypass the SSL authentication
        properties.put("mail.smtp.ssl.enable", false);
        properties.put("mail.smtp.starttls.enable", false);

        //帳號,密碼
        SmtpAuthenticator authentication
                = new SmtpAuthenticator(user, pwd);

        // 建立一個Session物件,並把properties傳進去
        Session mailSession = Session.
                getDefaultInstance(properties, authentication);

        try {
            //建立一個 MimeMessage object.
            MimeMessage message = new MimeMessage(mailSession);

            // 設定寄件人
            message.setFrom(new InternetAddress(from));

            // 設定收件人
            message.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(to));

            // 設定主旨
            message.setSubject(subject);

            //宣告一個BodyPart用以夾帶內文      
            BodyPart messageBodyPart = new MimeBodyPart();

            //設定內文
            messageBodyPart.setText(body);
            // 宣告一個multipart , 它可以使內文有不同的段落,
            //使其可以用用來夾帶內文及檔案
            Multipart multipart = new MimeMultipart();
            //把BodyPart加入Multipart(這個part夾帶內文)
            multipart.addBodyPart(messageBodyPart);
            //宣告一個BodyPart用以夾帶附加檔案
            BodyPart fileBodyPart = new MimeBodyPart();
            //要夾帶的檔案名稱
            String filename = 
                    "/Users/flowercatswets/Documents/lena.jpg";
            //讀取檔案
            DataSource source = new FileDataSource(filename);
            fileBodyPart.setDataHandler(new DataHandler(source));
            //設定附加檔案的名稱
            fileBodyPart.setFileName(filename);
            //把BodyPart加入Multipart(這個part夾帶檔案)
            multipart.addBodyPart(fileBodyPart);
            //設定eMultipart為messag的Content
            message.setContent(multipart );
            Transport transport = mailSession.getTransport();

            // 傳送信件         
            transport.send(message);

            System.out.println("發送成功");
        } catch (MessagingException mex) {
            mex.printStackTrace();
        }
    }

}

差異只在於原本單純的內文

//設定內文
message.setText(body);


變成多個part,一個part帶內文,一個part帶檔案
//宣告一個BodyPart用以夾帶內文      
BodyPart messageBodyPart = new MimeBodyPart();

//設定內文
messageBodyPart.setText(body);
// 宣告一個multipart , 它可以使內文有不同的段落,
//使其可以用用來夾帶內文及檔案
Multipart multipart = new MimeMultipart();
//把BodyPart加入Multipart(這個part夾帶內文)
multipart.addBodyPart(messageBodyPart);
//宣告一個BodyPart用以夾帶附加檔案
BodyPart fileBodyPart = new MimeBodyPart();
//要夾帶的檔案名稱
String filename = 
    "/Users/flowercatswets/Documents/lena.jpg";
//讀取檔案
DataSource source = new FileDataSource(filename);
fileBodyPart.setDataHandler(new DataHandler(source));
//設定附加檔案的名稱
fileBodyPart.setFileName(filename);
//把BodyPart加入Multipart(這個part夾帶檔案)
multipart.addBodyPart(fileBodyPart);
//設定eMultipart為messag的Content
message.setContent(multipart )


執行結果













資料來源
http://www.tutorialspoint.com/java/java_sending_email.htm

http://stackoverflow.com/questions/6610572/javax-mail-authenticationfailedexception-failed-to-connect-no-password-specifi

沒有留言:

張貼留言