搜尋此網誌

顯示具有 Javamail 標籤的文章。 顯示所有文章
顯示具有 Javamail 標籤的文章。 顯示所有文章

2013年9月27日 星期五

【Java】實作透過Gmail SMTP Server 發送信件 版本三

改寫版本二的內容(尚未測試,ps筆者跑太多次,gmail被暫停使用)
  1. 參考至這篇TLS加密並不是明文傳送。若要用密文傳送需要用SSL,且設定需要用SMTPS。
    (若需測試使用,下面兩行註解拿掉)
    // if (this.secureType == secureType.SSL)
    // protocol = SMTPS;
  2. 更貼近E-mail功能,使寄件者以及收信者均包含名字以及email地址,也可以設定同時多個收信者。所以增加:EmailSender和EmailReceiver。
  3. Properties 參數可以參考:Package com.sun.mail.smtp


EmailSender.java

class EmailSender{
	String name;
	String address;
	
	EmailSender(){
		name = "";
		address = "";
	}	
}
EmailReceiver.java

public interface EmailReceiver {
	String name();
	String address();
}

Email.java

package option;

import java.text.DateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Vector;

import javax.mail.Address;
import javax.mail.Message;
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;

import option.GmailSetting.SecureType;

public class Email {

	String subject;
	String content;
	SecureType secureType;
	boolean valid;
	String account;
	String passowrd;
	EmailSender emailSender;
	Vector<EmailReceiver> emailReceivers;

	static final String SMTP = "smtp";
	static final String SMTPS = "smtps";

	Email(SecureType secureType, boolean valid, String account, String password) {
		subject = "";
		content = "";
		this.secureType = secureType;
		this.valid = valid;
		this.account = account;
		this.passowrd = password;
		emailSender = new EmailSender();
		emailReceivers = new Vector<EmailReceiver>();
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public void setContents(String content) {
		this.content = content;
	}

	public void setSender(String name, String address) {
		emailSender.name = name;
		emailSender.address = address;
	}

	public void addReceiver(final String name, final String address) {
		emailReceivers.add(new EmailReceiver() {
			public String address() {
				return address;
			}

			public String name() {
				return name;
			}
		});
	}

	Properties generateRequireProp() {

		String protocol = SMTP;
		final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
		String portNumber = GmailSetting.PORT_NUMBER.get(secureType.value()).toString();

		//
		// if (this.secureType == secureType.SSL)
		// protocol = SMTPS;

		// set up gmail information
		Properties props = new Properties();
		props.setProperty("mail." + protocol + ".host", "smtp.gmail.com");
		props.setProperty("mail." + protocol + ".port", portNumber);
		props.setProperty("mail.transport.protocol", protocol);

		if (valid)
			props.setProperty("mail" + protocol + ".smtp.auth", "true");

		if (this.secureType != SecureType.None) {
			if (this.secureType == secureType.TLS)
				props.setProperty("mail." + protocol + ".smtp.starttls.enable", "true");
			else {
				props.setProperty("mail." + protocol + ".socketFactory.class", SSL_FACTORY);
				props.setProperty("mail." + protocol + ".socketFactory.fallback", "false");
				props.setProperty("mail." + protocol + ".socketFactory.port", portNumber);
				props.setProperty("mail." + protocol + ".smtps.ssl.enable", "true");

			}
		}
		return props;
	}

	boolean sendMail() {
		try {
			if (emailReceivers.isEmpty()) {
				System.out.println("Email Receiver is empty.");
				return false;
			}

			System.out.println("Start to send email");

			int receiverAddressCount = emailReceivers.size();
			Address[] mailAddress = new Address[receiverAddressCount];
			for (int i = 0; i < receiverAddressCount; i++) {
				mailAddress[i] = new InternetAddress(emailReceivers.get(i).address(), emailReceivers.get(i).name());
			}

			Address senderAddress = new InternetAddress(emailSender.address, emailSender.name);

			Properties props = generateRequireProp();

			// build the new session service
			Session session = Session.getInstance(props, null);

			Message message = new MimeMessage(session);

			// build the mail of sender , receiver and subject info
			message.setHeader("Content-Transfer-Encoding", "utf-8");
			message.setFrom(senderAddress);
			message.setRecipients(Message.RecipientType.TO, mailAddress);
			message.setSubject(subject);

			// set mime content
			MimeMultipart multipart = new MimeMultipart();
			MimeBodyPart messageBodyPart = new MimeBodyPart();
			messageBodyPart.setContent(content + "by " + secureType.value() + " connection.", "text/html;charset=utf-8");
			multipart.addBodyPart(messageBodyPart);
			message.setContent(multipart);

			message.saveChanges();
			String protocol = SMTP;

			if (valid) {
				Transport transport = session.getTransport();
				if (this.secureType == secureType.SSL)
					protocol = SMTPS;
				transport = session.getTransport(protocol);
				transport.connect("smtp.gmail.com", this.account, this.passowrd);
				Transport.send(message, message.getAllRecipients());
				transport.close();
			} else {
				Transport.send(message);

			}
			System.out.println("Done");

		} catch (Exception e) {
			// throw new RuntimeException(e);
			e.printStackTrace();
		}
		return true;

	}

	public static void main(String args[]) {

		final String senderAddr = "sender@gmail.com";
		final String password = "sender password";

		Email testEmail = new Email(SecureType.SSL, true, senderAddr, password);
		testEmail.setSubject("Test mail " + DateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis())));
		testEmail.setContents("This is a test e-mail by javamail library");
		testEmail.addReceiver("Test123", "receiver@mail");
		testEmail.setSender("SenderTest by Jorden", senderAddr);

		if (testEmail.sendMail())
			System.out.println("Success to send email!");

		else
			System.out.println("Error");
	}
}

2013年9月26日 星期四

【Java】實作透過Gmail SMTP Server 發送信件 版本二

本實作是改寫上篇透過SSL加密寄信;新增TLS以及None的方法。
因為Gmail已經不提供None(不加密)的寄信,所以在執行None方法時,會出現問題。

這部分除了改寫原本code以外,新增一個class放置gmail secure設定以及對應的port number。

Email.java


package option;

import java.text.DateFormat;
import java.util.Date;
import java.util.Properties;

import javax.mail.Authenticator;
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.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import option.GmailSetting.*;

public class Email {

	String subject;
	String content;
	String receiver;
	SecureType secureType;

	Email(SecureType secureType) {
		subject = "";
		content = "";
		receiver = "";
		this.secureType = secureType;
	}

	public void setSubject(String subject) {
		this.subject = subject;
	}

	public void setContents(String content) {
		this.content = content;
	}

	public void setReceiverAddress(String address) {
		this.receiver = address;
	}

	Properties generateRequireProp() {

		final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
		String portNumber = GmailSetting.PORT_NUMBER.get(secureType.value()).toString();

		// set up gmail smtp information
		Properties props = new Properties();
		props.setProperty("mail.smtp.host", "smtp.gmail.com");
		props.setProperty("mail.transport.protocol", "smtp");
		props.setProperty("mail.smtp.auth", "true");
		props.setProperty("mail.smtp.port", portNumber);

		if (this.secureType != SecureType.None) {
			if (this.secureType == secureType.TLS)
				props.setProperty("mail.smtp.starttls.enable", "true");
			else {
				props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
				props.setProperty("mail.smtp.socketFactory.fallback", "false");
				props.setProperty("mail.smtp.socketFactory.port", portNumber);
				props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
			}
		}
		return props;
	}

	boolean sendMail() {
		if (this.receiver.equals("")) {
			System.out.println("Email Receiver is empty.");
			return false;
		}

		System.out.println("Start to send email");
		Properties props = generateRequireProp();
		final String username = "sender@gmail.com";
		final String password = "sender password";

		// build the new session service
		Session session = Session.getInstance(props, new Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(username, password);
			}
		});

		try {
			Message message = new MimeMessage(session);

			// build the mail of sender , receiver and subject info
			message.setFrom(new InternetAddress(username));
			message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver, false));
			message.setSubject(subject);

			// set mime content
			MimeMultipart multipart = new MimeMultipart();
			MimeBodyPart messageBodyPart = new MimeBodyPart();
			messageBodyPart.setContent(content + "by " + secureType.value() + " connection.", "text/html;charset=utf-8");
			multipart.addBodyPart(messageBodyPart);
			message.setContent(multipart);

			Transport.send(message);
			System.out.println("Done");

		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return true;

	}

	public static void main(String args[]) {

		Email email = new Email(SecureType.SSL);
		email.setSubject("Test mail " + DateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis())));
		email.setContents("This is a test e-mail by javamail library");
		email.setReceiverAddress("receiver@mail");

		if (email.sendMail())
			System.out.println("Success to send email!");

		else
			System.out.println("Error");

	}
}


GmailSetting.java

package option;

import java.util.HashMap;
import java.util.Map;

public class GmailSetting {
	SecureType secureType;

	public GmailSetting() {
		// TODO Auto-generated constructor stub
	}

	public enum SecureType {
		None, SSL, TLS;

		public String value() {
			return name();
		}

		public static SecureType fromValue(String v) {
			return valueOf(v);
		}
	}

	static final Map<String, Integer> PORT_NUMBER = new HashMap<String, Integer>() {
		private static final long serialVersionUID = -5199045595923410899L;
		{
			put("None", 25);
			put("SSL", 465);
			put("TLS", 587);
		}
	};

}

2013年9月25日 星期三

【Java】實作透過Gmail SMTP Server 發送信件(利用javamail API)

連線加密方式有三種:
  1. None(不加密)
  2. TLS , port number:587
  3. SSL , port number:465 (參考網址)
這裡實作以SSL加密寄送信件。
需要包裝javamail API到lib,下例用JavaMail 1.4.2進行包裝。

注意: 若發送信件內容,不只是純文字,而有用到html、CSS。
經過測試後,確定gmail 不支援部分block css內容,若可行,請寫inline css。
其他html email設計的要素,參考:
  1. Guide to CSS support in email 
  2. How HTML email works, basic concepts, best practices, tips and tricks

package option;

import java.text.DateFormat;
import java.util.Date;
import java.util.Properties;

import javax.mail.Authenticator;
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.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class Email {

 String subject;
 String content;
 String receiver;

 Email() {
  subject = "";
  content = "";
  receiver = "";
 }

 public void setSubject(String subject) {
  this.subject = subject;
 }

 public void setContents(String content) {
  this.content = content;
 }

 public void setReceiverAddress(String address) {
  this.receiver = address;
 }

 static Properties generateRequireProp() {

  final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
  
  // set up gmail information
  Properties props = new Properties();
  props.setProperty("mail.smtp.host", "smtp.gmail.com");
  props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
  props.setProperty("mail.smtp.socketFactory.fallback", "false");
  props.setProperty("mail.smtp.socketFactory.port", "465");
  props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
  props.setProperty("mail.smtp.auth", "true");
  props.setProperty("mail.smtp.port", "465");

  return props;
 }

 boolean send() {
  if (receiver.equals("")) {
   System.out.println("Email Receiver is empty.");
   return false;
  }

  Properties props = generateRequireProp();
  final String username = "sender@gmail.com";
  final String password = "sender password";

  // build the new session service
  Session session = Session.getInstance(props, new Authenticator() {
   protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(username, password);
   }
  });

  try {   
   Message message = new MimeMessage(session);
   
   //build the mail of sender , receiver and subject info 
   message.setFrom(new InternetAddress(username));
   message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver, false));
   message.setSubject(subject);
   
   // set mime content
   MimeMultipart multipart = new MimeMultipart();
   MimeBodyPart messageBodyPart = new MimeBodyPart();
   messageBodyPart.setContent(content, "text/html;charset=utf-8");
   multipart.addBodyPart(messageBodyPart);
   message.setContent(multipart);

   Transport.send(message);
   System.out.println("Done");

  } catch (Exception e) {
   throw new RuntimeException(e);
  }
  return true;

 }

 public static void main(String args[]) {

  Email email = new Email();
  email.setSubject("Test mail "+DateFormat.getDateTimeInstance().format(new Date(System.currentTimeMillis())));
  email.setContents("This is a test e-mail by javamail library");
  email.setReceiverAddress("receiver@mail");

  if (email.send())
   System.out.println("Sending is successing");

  else
   System.out.println("Error");

 }
}