Apusic上用JavaMail發(fā)郵件
0. JavaMail基本介紹
?JavaMail是屬于J2EE框架中的一部分,主要是為簡(jiǎn)化Mail部分開(kāi)發(fā)工作。使用JavaMail發(fā)送郵件需要以下步驟:
?1)初始化Session實(shí)例;
?在初始化Session實(shí)例中有兩種方式:使用JNDI初始化和在代碼中自行完成初始化。
?★ 如果SMTP不需要認(rèn)證,則不再做其他工作;
?★ 如果SMTP需要認(rèn)證,則確定在Session中提供嵌入認(rèn)證信息,還是由3)Transport完成認(rèn)證過(guò)程。
?2)初始化Message實(shí)例,填充相關(guān)信息;
?3)初始化Transport實(shí)例,連接到遠(yuǎn)程SMTP服務(wù)器,發(fā)送郵件。
?在初始化Transport實(shí)例時(shí)也有兩種情況:
?★ 如果SMTP不需要認(rèn)證,可以直接調(diào)用send()函數(shù)發(fā)送郵件,應(yīng)用服務(wù)器會(huì)在后臺(tái)調(diào)用connect()函數(shù)完成誰(shuí),進(jìn)行郵件發(fā)送;
?★ 如果SMTP需要認(rèn)證,需要調(diào)用connect()函數(shù),并提供認(rèn)證需要的用戶(hù)名/密碼,才可以正確發(fā)送郵件。
?
1. javax.mail.Session的初始化
1.1. 使用JNDI初始化(配置JavaMail的JNDI)
在Apusic的J2EE應(yīng)用中找到apusic-application.xml文件,增加<mail-session>部分,示例如下:
<apusic-application>
?<module uri="web.war">
??<web />
?</module>
?<mail-session>
??<jndi-name>javamail/myMail</jndi-name>
??<property name="mail.transport.protocol" value="smtp" />
??<property name="mail.smtp.host" value="smtp.163.com" />
??<property name="mail.smtp.user" value="user" />
??<property name="mail.smtp.password" value="password" />
??<property name="mail.smtp.auth" value="true" />
??<property name="mail.from" value="user@163.com" />
?</mail-session>
</apusic-application>
1.1.1. 通過(guò)JNDI找到JavaMail
1.1.1.1. 使用遠(yuǎn)程訪(fǎng)問(wèn)獲得JavaMail
?Hashtable env=new Hashtable();
?env.put(Context.INITIAL_CONTEXT_FACTORY,"com.apusic.naming.jndi.CNContextFactory");
?env.put(Context.PROVIDER_URL,"iiop://localhost:6888");
?//插入相關(guān)驗(yàn)證信息
?env.put(Context.SECURITY_CREDENTIALS,"admin" ) ;
?env.put(Context.SECURITY_PRINCIPAL,"admin");
?Context initCtx=new InitialContext(env);
?System.out.println(initCtx.PROVIDER_URL);
?//通過(guò)RMI 取得
?Session myMailSession = (Session) initCtx.lookup("javamail/myMailNoAuth");
1.1.1.2. 使用Apusic默認(rèn)方式獲得JavaMail
?Context initCtx = new InitialContext();
?Session myMailSession = (Session) initCtx.lookup("javamail/myMailNoAuth");
?System.out.println(myMailSession.getProperty("mail.smtp.host"));
?
1.1.2. 通過(guò)資源注入配置JavaMail
?@Resource(mappedName = "javamail/myMailAuth", type = javax.mail.Session.class, shareable = true, authenticationType = Resource.AuthenticationType.CONTAINER, description = "my email with auth")
?private Session myAuthMailSession;
或者
?@Resource(mappedName = "javamail/myMailAuth")
?private Session myAuthMailSession;
1.2. 在代碼中初始化
1.2.1. 無(wú)須認(rèn)證的初始化
?final Properties props = new Properties();
?props.put("mail.transport.protocol", "smtp");
?props.put("mail.smtp.auth", "false");
?props.put("mail.smtp.host", "localhost");
?Session myMailSession = Session.getInstance(props);
1.2.2. 需要認(rèn)證的初始化(Session實(shí)例構(gòu)造時(shí)提供認(rèn)證支持)
?final Properties props = new Properties();
?props.put("mail.transport.protocol", "smtp");
?props.put("mail.smtp.auth", "true");
?props.put("mail.smtp.host", "smtp.163.com");
?Session myMailSession = Session.getInstance(props, new Authenticator() {
??public PasswordAuthentication getPasswordAuthentication() {
???return new PasswordAuthentication("user", "password");}?});
1.2.3. 需要認(rèn)證的初始化(Session配置參數(shù)提供認(rèn)證支持)
?myMailSession.setPasswordAuthentication(
??new URLName(props.getProperty("mail.transport.protocol")+"://"+??
???????????????? props.getProperty("mail.smtp.user")+"@"+??
???????????????? props.getProperty("mail.smtp.host")),??
??????? new PasswordAuthentication(props.getProperty("mail.smtp.user"),??
???????????????? props.getProperty("mail.smtp.password")));??
1.2.4. 需要認(rèn)證的初始化(Transport配置參數(shù)提供認(rèn)證支持)
??// 發(fā)送郵件
??javax.mail.Transport myTransport = myMailSession.getTransport("smtp");
??myTransport.connect("smtp.163.com", "user", "password");
??myTransport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
??myTransport.close();
???
1.4. 對(duì)Session調(diào)試的配置
●?可以在mail-session中加入<property name="mail.debug" value="true" />
●?可以在Session初始化前加入props.put("mail.debug", "true");
●?可以在Session初始化后,通過(guò)代碼控制myMailSession.setDebug(true);
1.5. Properties的解釋
◆?mail.store.protocol:用于檢索郵件的協(xié)議
◆?mail.transport.protocol:用于傳送郵件的協(xié)議
◆?mail.host:默認(rèn)的主機(jī)名,默認(rèn)是本地計(jì)算機(jī)。
◆?mail.user:默認(rèn)的用戶(hù)名。
◆?mail.from:默認(rèn)的返回地址。
◆?mail.debug:是否輸出DEBUG信息。默認(rèn)為False。
◆?mail.protocol.host:指定協(xié)議的主機(jī)名,沒(méi)有指定就用mail.host。例如:mail.smtp.host=smtp.163.com
◆?mail.protocol.user:指定協(xié)議的用戶(hù)名,沒(méi)有指定就用mail.user。例如:mail.smtp.user=user
◆?mail.protocol.from:指定協(xié)議的返回地址,沒(méi)有指定就用mail.from。例如:mail.smtp.from=user@163.com
◆?mail.smtp.auth:如果是True,就會(huì)登錄SMTP服務(wù)器,獲得授權(quán)才能發(fā)送郵件。默認(rèn)為False。
2. 通過(guò)JavaMail發(fā)送郵件
2.1. 通過(guò)無(wú)須認(rèn)證的SMTP發(fā)郵件
??final Properties props = new Properties();
??props.put("mail.transport.protocol", "smtp");
??props.put("mail.smtp.auth", "false");
??props.put("mail.smtp.host", "localhost");
??try {
???Session myMailSession = Session.getInstance(props);
???myMailSession.setDebug(true); // 打開(kāi)DEBUG模式
???Message msg = new MimeMessage(myMailSession);
???msg.setFrom(new InternetAddress("user@163.com"));
???msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse("zhuyuanxiang@apusic.com"));
???msg.setContent("I have a email test!", "text/plain");
???msg.setSentDate(new java.util.Date());
???msg.setSubject("Test");
???msg.setText("This is a test!\n");
???System.out.println("1.Please wait for sending one...");
???// 發(fā)送郵件
???// javax.mail.Transport.send(msg); // 與下面四行的功能一樣
???javax.mail.Transport myTransport = myMailSession.getTransport("smtp");
???myTransport.connect();
???myTransport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
???myTransport.close();
???
???System.out.println("2.Your message had send!");
??} catch (Exception error) {
???System.out.println("*.I am sorry to tell you the fail for " + error);
??}
注:測(cè)試可以使用Microsft IIS SMTP 服務(wù),安裝好啟動(dòng)服務(wù)后,還需要進(jìn)入“IIS管理器”,增加一個(gè)“遠(yuǎn)程域”,對(duì)于“遠(yuǎn)程域”的“出站安全性”需要把用戶(hù)名和密碼加上(就是平時(shí)發(fā)郵件時(shí)登錄用的用戶(hù)名/密碼),否則郵件發(fā)不出去。
2.2. 通過(guò)需要認(rèn)證的SMTP發(fā)郵件
2.2.1. 需要認(rèn)證的初始化(Session實(shí)例構(gòu)造時(shí)提供認(rèn)證支持)
?final Properties props = new Properties();
?props.put("mail.transport.protocol", "smtp");
?props.put("mail.smtp.auth", "true");
?props.put("mail.smtp.host", "smtp.163.com");
?try {
??Session myMailSession = Session.getInstance(props, new Authenticator() {
???public PasswordAuthentication getPasswordAuthentication() {
????return new PasswordAuthentication("user", "password");
???}
??});
??myMailSession.setDebug(true);?// 打開(kāi)DEBUG模式
??InternetAddress address = new InternetAddress("user@163.com");
??String message = "I have a email test!";
??Message msg = new MimeMessage(myMailSession);
??msg.setFrom(address);
??msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse("zhuyuanxiang@apusic.com"));
??msg.setContent(message, "text/plain");
??msg.setSentDate(new java.util.Date());
??msg.setSubject("Test");
??msg.setText("This is a test!\n");
??out.println("1.Please wait for sending...");
??
??// 發(fā)送郵件
??javax.mail.Transport myTransport = myMailSession.getTransport("smtp");
??myTransport.connect();
??myTransport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
??myTransport.close();
??// javax.mail.Transport.send(msg);?// 注釋上四行,打開(kāi)這行代碼,功能一樣
??out.println("2.Your message had send!");
?} catch (Exception error) {
??out.println("*.I am sorry to tell you the fail for " + error);
?}
2.2.2. 需要認(rèn)證的初始化(Session配置參數(shù)提供認(rèn)證支持)
?final Properties props = new Properties();
?props.put("mail.transport.protocol", "smtp");
?props.put("mail.smtp.auth", "true");
?props.put("mail.smtp.host", "smtp.163.com");
?try {
??Session myMailSession = Session.getInstance(props);
??myMailSession.setDebug(true);?// 打開(kāi)DEBUG模式
??myAuthMailSession.setPasswordAuthentication(
???new URLName("smtp://user@host", new PasswordAuthentication("user","password"));?
??InternetAddress address = new InternetAddress("user@163.com");
??String message = "I have a email test!";
??Message msg = new MimeMessage(myMailSession);
??msg.setFrom(address);
??msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse("zhuyuanxiang@apusic.com"));
??msg.setContent(message, "text/plain");
??msg.setSentDate(new java.util.Date());
??msg.setSubject("Test");
??msg.setText("This is a test!\n");
??out.println("1.Please wait for sending...");
??
??// 發(fā)送郵件
??javax.mail.Transport myTransport = myMailSession.getTransport("smtp");
??myTransport.connect();
??myTransport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
??myTransport.close();
??// javax.mail.Transport.send(msg);?// 注釋上四行,打開(kāi)這行代碼,功能一樣
??out.println("2.Your message had send!");
?} catch (Exception error) {
??out.println("*.I am sorry to tell you the fail for " + error);
?}
2.2.3. 需要認(rèn)證的初始化(Transport配置參數(shù)提供認(rèn)證支持)
??final Properties props = new Properties();
??props.put("mail.transport.protocol", "smtp");
??props.put("mail.smtp.auth", "true");
??try {
???Session myMailSession = Session.getInstance(props);
???myMailSession.setDebug(true); // 打開(kāi)DEBUG模式
???Message msg = new MimeMessage(myMailSession);
???msg.setFrom(new InternetAddress("user@163.com"));
???msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse("zhuyuanxiang@apusic.com"));
???msg.setContent("I have a email test!", "text/plain");
???msg.setSentDate(new java.util.Date());
???msg.setSubject("Test");
???msg.setText("This is a test!\n");
???System.out.println("1.Please wait for sending two...");
???// 發(fā)送郵件
???javax.mail.Transport myTransport = myMailSession.getTransport("smtp");
???myTransport.connect("smtp.163.com", "user", "password");
???myTransport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
???myTransport.close();
???// javax.mail.Transport.send(msg); // 這行不能使用。
???System.out.println("2.Your message had send!");
??} catch (Exception error) {
???System.out.println("*.I am sorry to tell you the fail for " + error);
??}
?}
注:資源注入的Session發(fā)送郵件時(shí):
無(wú)須認(rèn)證的SMTP,可以參考2.1.
需要認(rèn)證的SMTP,可以參考2.2.1.
參考:
http://java.sun.com/products/javamail/javadocs/com/sun/mail/smtp/package-summary.html
http://commons.apache.org/email/userguide.html
http://m.tkk7.com/Unmi/archive/2007/06/07/124179.html
http://unmi.blogcn.com/diary,117630488.shtml
Apusic Stduio打包的示例工程。
http://zhuyuanxiang.javaeye.com/topics/download/d6f5c3a9-9cd9-30be-9b64-9e311900b304
備注:本文耗時(shí)1周完成。