服務器端(請點擊跳轉)
背景介紹:
曾經郵件服務器的開發很賺錢,如丁磊就是做郵件服務發家的。
比較有意義的項目時將郵件內容發佈成bbs的帖子。
辦公自動化項目(OA)都要附帶發送郵件的功能,如發送通知等。
許多網站項目也都需要附帶發送郵件的功能,如:給新註冊的用戶自動發送一封包含其註冊信息的歡迎E-Mail、給過生日的註冊會員自動發送一封表示祝賀的E-Mail、將網站的最新活動信息通過E-Mail發送給所有的註冊會員。
主要分爲:發送與接收郵件、創建與解析郵件內容。
郵件服務器主要提供以下功能:
(1)接收用戶投遞的郵件;
(2)將用戶投遞進來的郵件轉發給目標郵件服務器;
(3)接收其他郵件服務器轉發來的郵件並把郵件存儲到其管理的用戶郵中;
(4)爲前來讀取郵件的用戶提供讀取服務。
郵件服務器按通訊協議可以劃分爲:
(1)SMTP服務器。用於替用戶發送郵件和接收外面發送給本地用戶的郵件。
(2)POP3/IMAP服務器。用於幫助用戶讀取SMTP服務器接收進來的該用戶的郵件。
開發環境準備:
>提前在sina和sohu上開設一個免費的賬號;
>獲取smtp和pop3服務器的名稱;
>在outlook中配置sina賬戶;
>使用outlook發送和接收郵件。
1. 如何獲取sina的smtp和pop3服務器地址?
進入郵箱的登錄頁面,新浪郵箱如下:
點擊右下角的“幫助”
點擊左側邊欄的“免費郵箱pop3和smtp服務器”選項
頁面給出了新浪的服務器地址。
其他的郵箱如Gmail的可能不太一樣,不過也很好找,在此我就不說明了,可以google。
2.配置outlook(此處我嘗試以自己的Gmail做例子)。
打開Outlook Express,點擊“工具”、“賬戶”、“添加”、“郵件”、彈出對話框
輸入“gmail”、輸入郵箱地址
輸入pop3和smtp地址
填寫郵箱的用戶名和密碼
然後完成添加賬戶。同樣可以添加多個郵箱賬號。
注:因爲本人用的是Gmail郵箱,還需要設置下賬戶的屬性,點“屬性”,
點“高級”
將smtp設爲465,pop3設爲995,然後點擊“確定”。
點擊“工具”、“發送和接收”、“接收全部郵件”
就完成了outlook和Gmail郵箱的關聯。
-
此處是搜狐向新浪郵箱傳郵件(可以大致
-
瞭解,此處只是說明outlook用smtp服務器發送
-
郵件的原理
注:SMTP服務器的通信過程(“>>”用戶向服務器發送信息,“<<”服務器向用戶發送信息。)
查詢本機ip地址:192.168.216.1;
連接gmail的smtp服務器(注意,郵件的端口爲25)
輸入“ehlo 192.168.216.1”,顯示如下:
以上是如sohu這樣的smtp服務器的地址解析。
輸入“nslookup”、“set type=mx”、“google.com”來解析gmail的smtp服務器的地址,如下:
退出之後連接gmail服務器“telnet google.com.s9a2.psmtp.com”
ps:忘了在後面加25端口了,尷尬!!
輸入“ehlo 192.168.1.8 ”,如下:
以上是如sina的smtp服務器的地址解析。
下面開始寫郵件:(此處gmail郵箱寫郵件失敗,具體原因我下面會介紹!以下是sina服務器下的寫郵件)
最後就可以去outlook中查看收件箱了。
如果發送出錯,可以勾選下面窗口中的“我的服務器要求身份驗證”一項
sina服務器的運行原理
————————因爲是用gmail做的實驗,所以在後面寫信息的時候是不暢通的,具體原因一會介紹,———————————————
———————— 但是獲取smtp服務器地址的步驟是正確的。—— —— —————————————————————————————————————————————————————————————
問題:Gmail的smtp服務器寫信息不暢通的原因?
問題解決:Gmail需要SSL 驗證,所以我們只能用outlook這種客戶端軟件來連接服務器發送郵件。
問題:爲什麼要用 Gmail 的 SMTP 服務器?
問題解決:一般的網站都不會自己建 SMTP 服務器,畢竟有些麻煩。而且也不是隨便建一個 SMTP 服務器就能得到其它郵件服務器的認可。例如:你購買的網站空間是與其它網站共享一個 IP 地址(動態 IP),這樣即使你建一個 SMTP 服務器,也很容易被其它郵件服務器認爲不可靠。這就好比一個沒有自己辦公地點的公司,與擁有大面積廠房或者寫字樓的公司相比,哪個更可靠?這種動態 IP 的 SMTP 服務器很容易被認爲是“垃圾郵件發送者”。例如,spamhaus.org 這個網站就很容易將你的 SMTP “私服”列入黑名單,很多郵件服務器會到這個名單上覈對,如果發現來信的 IP 已列入 spamhaus 黑名單,你的郵件就會被拒收。
舉例來說,與你共享 IP 的其它某個網站自己建了 SMTP 服務器,發送了惡意郵件,被接收方標記爲“垃圾郵件”並提交給 spamhaus,那麼這個 IP 上所有的網站都受牽連。你建的 SMTP 服務器一樣被拒絕,因爲 spamhaus 名單上只寫 IP 。
因此,我建議使用其它免費郵件商提供的 SMTP 服務。在這麼多免費郵件中,我推薦使用 Gmail 的 SMTP 服務。
Gmail 帳號不僅是一個郵件帳號,它更是“Google 帳號”。擁有了 Gmail 帳號,就能登錄Google 的網站流量分析系統、Google Group、Gtalk 即時通訊工具、Google Code、Google Calendar 等等在線服務。你就相當於擁有了一個使用範圍很廣的 Passport 通行證。
單就郵件功能來說,Gmail 也是非常不錯的。默認 6GB 空間,強大的郵件搜索功能,使得你幾乎不用刪除郵件。同一主題的郵件往來以會話(Thread)形式疊聯顯示,也是一大創舉。它還提供了免費的 POP3 和 SMTP 服務,方便用戶通過 Outlook Express 等郵件客戶端軟件收發郵件。
問題:Gmail 的 SMTP 郵件限量?
問題解決:爲了防止有人利用 Gmail 的免費 SMTP 服務發送大量垃圾郵件,Gmail 規定:每個帳號通過 SMTP 每天只能發給 100 個收件人(注意:不是 100 封郵件,這個限制更嚴格),超過這個數量就被封號24小時;如果你登錄到 Gmail 的 web 界面,則每天可以發給 500 個收件人,超過這個數量也會被封號 24 小時。
如果你的網站註冊人數很多,或者論壇發帖量很大,則每天發送的激活/通知郵件很容易超過 100 封,這就違反了 Gmail 的規定,會被停用帳號 24 小時。
這樣來說,Gmail 的 SMTP 不能用在大型網站。如果你的網站每天發送的激活/通知郵件不超過 100,我推薦使用 Gmail SMTP;如果超過這個數量,就需要尋找其它不限量的 SMTP,或者自己搭建一個 SMTP 了 —— 大型網站都會這麼做。
問題:自己搭建 SMTP 服務器?
問題解決:搭建了一個 SMTP 服務器,用的是 Postfix for FreeBSD 程序。在測試時發現兩個問題,就是下面提醒裏面的,目前都已經解決。
自己搭建 SMTP 服務器的好處是:沒有信件限量,或者說作爲 Postmaster 你有完全的權限控制限量多少。另外,速度也很快,如果你沒有開設大量帳號的話。
藉助開源的 ExtMail 軟件,你還可以給你的郵件服務器創建 Web 界面,這樣你就得到一個名副其實的電子郵局了。如果你想給會員權限來註冊免費電郵都可以。
最後提醒一下:
1)、如果你自己搭建的 SMTP 發送郵件時發現被拒收,很可能是因爲被 spamhaus.org 列入黑名單,你可以到他們網站進行搜索。如果證實被誤判爲垃圾郵件發送源,就可以申訴,請求解除封鎖。已經有熱心網友撰寫了《spamhaus的PBL申訴圖解》 ,你可以參考一下。
2)、發往 Hotmail 的郵件會被微軟服務器進行反向解析,如果解析失敗就拒收。因此自己搭建 SMTP 服務器時注意必須同時做好反向解析。
3)、如果你用 Gmail 或其他要求 SSL 連接的 SMTP 服務器時,發現設置正確但是無法發出郵件,請檢查一下你的網站服務器是否支持以 SSL 協議訪問外部 URL —— 問問你的空間商吧。
當然,這裏我們需要自己用java來編寫smtp服務
器,所以以上知識點僅供建立網站時候使用。
3.什麼是java mail?
JavaMail是sun公司爲方便java開發人員在應用程序中實現郵件發送和接收功能而提供的一套標準開發包,它支持一些常用的郵件協議,如smtp、pop3、impa。用javamail編程就不需要考慮底層細節了。分爲message類(創建和解析郵件內容的api)、transport類(發送郵件api)、store(接收郵件的api)、session類(用於定義應用程序所需的環境信息以及收集客戶端與郵件服務器建立網絡連接的會話信息)。
去網上下載javamail。
4.主要照着給的pdf文檔學習。
/*這是一個最簡單的發送郵件客戶端*/
import java.util.Properties;
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.MimeMessage;
public class Demo1 {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
Properties props = new Properties();
/*props.setProperty("mail.smtp.ssl.enable", "true");*//*如果是由ssl驗證的,可以設置這個屬性爲true*/
props.setProperty("mail.smtps.auth", "true");/*寫信時要通過身份驗證,就設置屬性爲true*/
props.setProperty("mail.transport.protocol", "smtps");/*如果想用通信協議生效,就設置這個屬性爲true*/
Session session = Session.getInstance(props);/*首先建立個會話*/
session.setDebug(true);
Message msg = new MimeMessage(session);/*第二步,建立message*/
msg.setText("你好嗎?");
msg.setFrom(new InternetAddress("[email protected]"));
Transport transport = session.getTransport();/*最後建立連接*/
transport.connect("smtp.gmail.com",465, "p330316117", "py8907935");
transport.sendMessage(msg, new Address[] { new InternetAddress(
"[email protected]") });
// transport.send(msg,new Address[]{new
// InternetAddress("[email protected]")});
transport.close();
}
}
/*一共就3步,我們可以去api文檔中查看所需要的類和它們的方法*/
/*
可發送給多個收件人*/
import java.io.FileInputStream;
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.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class Demo2 {
/**
* @param args add by zxx ,Feb 5, 2009
*/
public static void main(String[] args) throws Exception{
/*只是Demo1的改寫*/
Properties props = new Properties();
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.host", "smtp.gmail.com");/*服務器的地址*/
props.setProperty("mail.smtp.ssl.enable", "true");
Session session = Session.getInstance(props,
new Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication("p330316117","py8907935");
}
}
);
session.setDebug(true);
/* Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("[email protected]"));//發件人
msg.setSubject("中文主題");
msg.setRecipients(RecipientType.TO,
InternetAddress.parse("[email protected],[email protected]"));//發送多個收件人
msg.setContent("<span style='color:red'>中文呵呵呵</span>", "text/html;charset=gbk");
msg.setContent("你好", "text/html;charset=gbk");
Transport.send(msg);*/
Message msg = new MimeMessage(session,new FileInputStream("resouce//demo3.eml")); /*讀取Demo3寫的一封複雜的郵件發送出去*/
Transport.send(msg,InternetAddress.parse("[email protected]"));
}
}
項目目錄結構
/*
一封複雜的郵件*/
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.Session;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;
public class Demo3 {
/**
* @param args add by zxx ,Feb 5, 2009
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
Session session = Session.getInstance(new Properties());
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("/"" + MimeUtility.encodeText("老潘") + "/" <[email protected]>"));
msg.setSubject("你們的Java培訓真的是最牛的嗎?");
msg.setReplyTo(new Address[]{new InternetAddress("[email protected]")});
msg.setRecipients(RecipientType.TO,InternetAddress.parse(MimeUtility.encodeText("黎活明") + " <[email protected]>," + MimeUtility.encodeText("張孝祥") + " <[email protected]>"));
MimeMultipart msgMultipart = new MimeMultipart("mixed");
msg.setContent(msgMultipart);
MimeBodyPart attch1 = new MimeBodyPart();
MimeBodyPart attch2 = new MimeBodyPart();
MimeBodyPart content = new MimeBodyPart();
msgMultipart.addBodyPart(attch1);
msgMultipart.addBodyPart(attch2);
msgMultipart.addBodyPart(content);
DataSource ds1 = new FileDataSource(
"resource//bookmark.txt"
);
DataHandler dh1 = new DataHandler(ds1 );/*數據處理,用來包裝附件文件*/
attch1.setDataHandler(dh1);
attch1.setFileName(
MimeUtility.encodeText("bookmark.txt")/*附件名稱*/
);
DataSource ds2 = new FileDataSource(
"resource//slogo.gif"
);
DataHandler dh2 = new DataHandler(ds2 );
attch2.setDataHandler(dh2);
attch2.setFileName("slogo.gif");
MimeMultipart bodyMultipart = new MimeMultipart("related");
content.setContent(bodyMultipart);
MimeBodyPart htmlPart = new MimeBodyPart();
MimeBodyPart gifPart = new MimeBodyPart();
bodyMultipart.addBodyPart(htmlPart);
bodyMultipart.addBodyPart(gifPart);
DataSource gifds = new FileDataSource(
"resource//logo.gif"
);
DataHandler gifdh = new DataHandler(gifds);
gifPart.setDataHandler(gifdh);
gifPart.setHeader("Content-Location", "http://www.itcast.cn/logo.gif");/*圖片代表的位置*/
htmlPart.setContent("這可是我自己用程序生成和發送的郵件哦!<img src='http://www.itcast.cn/logo.gif'>"
, "text/html;charset=gbk");
msg.saveChanges();
OutputStream ips = new FileOutputStream("resource//demo3.eml");
msg.writeTo(ips);
ips.close();
}
}
用servlet來作爲郵件客戶端
這裏我們做一個demo2.jar也就是用上面第二個程序來發送郵件。將它導入到新建web project項目的lib中。這裏一定要注意
Message msg = new MimeMessage(session,new FileInputStream("resouce//demo3.eml")); /*讀取Demo3寫的一封複雜的郵件發送出去*/
將demo3.eml的路徑改成絕對路徑(在jar包中指引絕對路徑),如果你想指引相對路徑,就要做如下操作:請訪問我“jar包中訪問資源”。
文件目錄如下
servlet代碼:
package com.JavaMailExplOnNet;
import java.io.IOException;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.JavaMailExpl.Demo2;
public class SendMailServlet extends HttpServlet {
/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
Demo2.main(new String[]{});
/*以下是tomcat的jndi發送郵件的需要,在META-INF中的context.xml是它的配置文件*/
/*Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
Session session = (Session) envCtx.lookup("mail/Dog");
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("[email protected]"));
InternetAddress to[] = new InternetAddress[1];
to[0] = new InternetAddress("[email protected]");
message.setRecipients(Message.RecipientType.TO, to);
message.setSubject("ha");
message.setText("test");
//Transport.send(message);
Transport transport = session.getTransport();
transport.connect("smtp.gmail.com", "p330316117", "py8907935");
transport.sendMessage(message, to);
transport.close();*/
response.getWriter().print("ok!");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace(response.getWriter());
}
}
}
然後改寫web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>SendMailServlet</servlet-name>
<servlet-class>com.JavaMailExplOnNet.SendMailServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SendMailServlet</servlet-name>
<url-pattern>/servlet/SendMailServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
將mail包放入/WEB-INF/lib目錄中,然後部署到tomcat上運行,在瀏覽器中輸入“http://localhost:8080//JavaMailExplOnNet/servlet/SendMailServlet”,得到一封郵件。
一般我們是將郵件交給servlet,然後讓servlet發送郵件,而我們只是給它發指令,功能圖如下:
tomcat本身也提供了對java mail的支持,請看jndi的幫助文檔。(這個我不想介紹了!)
只需要寫一個META-INF/context.xml:
<Context>
<Resource name="mail/Dog" auth="Container"
type="javax.mail.Session"
mail.smtp.host="smtp.sina.com" mail.smtp.auth="true"
mail.transport.protocol="smtp"
/>
</Context>