摘 要:郵件群發是消息在Internet傳遞的最好辦法,同時也是垃圾郵件的來源。本文以使用JAVAMAIL為例,討論實現大規模郵件發送的方法和技巧。 關鍵字:SMTP、MIME、JAVAMAIL、群發郵件
一、引言 郵件群發是Internet生活中最常見的一種信息傳遞方式,其傳遞信息的主動性、高效率和低費用而被眾多商家廣泛采用。我們的電子郵箱隨之充滿了各種類型的商業郵件,一般稱這些商業郵件為垃圾郵件。本文筆者運用JAVA語言開發了一個基于SMTP服務器的郵件群發軟件,在以下內容中將逐一介紹SMTP協議,JAVAMAIL包,以及郵件群發程序的片段等。 二、簡單郵件傳輸協議與JAVAMAIL類庫 1.簡單郵件傳輸協議(SMTP)從1982年起被用來在不同計算機系統間傳遞電子郵件。SMTP使用簡單的ASCII碼文本命令,命令定義長度為4個字符。SMTP基本命令集及功能如表一所示。
表一 絕大多數SMTP系統采用一種標準的郵件報文格式,即RFC822來“規范”郵件的形式。RFC822明確的劃分郵件為兩個部分,一部分稱為郵件頭,起其作用是標識郵件;第二部分是郵件體。 郵件頭中包括: 1)Received:用來標識將郵件從最初發送者到目的地進行中間轉發的SMTP服務器,其中含有發信人及發信服務器真實的信息。 2)Return-path:用來標識郵件發送到目的服務器所經過的路徑。 3)From:顯示發信人的地址。格式為From:user-name。 4)Date:記錄郵件發送時間。 5)Destination:記錄收郵件地址, 標識電子郵件的接受方地址,這些地址是純粹地信息,SMTP僅通過RCPT命令發送信件。包括To主收件人,Cc抄送收件人,Bcc暗抄送收件人,格式為To/Cc/Bcc:address。 6)Resent:表示一封郵件處于某中原因需要從客戶端再次發送。 2.JAVAMAIL關于郵件操作最新包是JavaMail1.2,有四個大類,如表二所示。
表二 這些類操作分別屬于mailapi.jar(文件包含核心API類),smtp.jar(實現SMTP協議功能),pop3.jar(實現POP3協議功能),imap.jar(包含IMAP協議功能)等四個文件。同時這四個文件都被包含在mail.jar中,如過圖省事的話,直接包含mail.jar即可。 如果要實現帶附件的郵件收發功能,還需要包含activation.jar,它提供通過二進制數據流的形式處理MIME類型的訪問。 |
三、程序舉例 1.首先是連接SMTP服務器,JAVAMAIL1.2不能實現SMTP服務的功能,但可以連接已有的SMTP服務器。 //創建一個屬性對象 Properties props=System.getProperties(); //創建系統屬性對象 props.setProperty("mail.transport.protocol","smtp"); //設置使用smtp協議 props.setProperty("mail.smtp.host",server); //設置SMTP服務器地址 props.setProperty("mail.smtp.port",""+port); //設置SMTP端口號 props.setProperty("mail.smtp.auth","true"); //SMTP服務用戶認證 //創建一個過程對象 javax.mail.Session sess = javax.mail.Session.getDefaultInstance(props, null); 2.創建一封新郵件,一般定義該MimeMessage創建一個郵件對象。 MimeMessage msg=new MimeMessage(sess); //創建郵件對象 msg.setSubject(“郵件群發”); //設置郵件主題 msg.setSentDate(new Date()); //設置發信日期 msg.setFrom(Address address); //設置發信人 郵件地址只要符合帶有“@”符號并且使用“.”分成三段的字符串都會被SMTP服務器接受,發送廣告郵件的商家一般都會在這里修改發信人地址,所以我們的收件箱中看見的廣告郵件顯示中發信人內容一些的根本不存在郵件地址。如果想查看真正地發信人,應該查看郵件頭中Received的內容。 //設置主收件人 msg.setRecipients(Message.RecipientType.TO,Address toaddress); //設置抄送收件人 msg.addRecipients(Message.RecipientType.CC,Address coaddress); //設置暗抄送人 msg.addRecipients(Message.RecipientType.BCC,Address bcoaddress); SMTP允許一封郵件有多個接受者,我們可以利用這個特點,在這三個收件人中填寫多個收件人地址來提高大規模發郵件效率。另外Bcc這個字段可以隱藏收件人的地址,你有時可能發現郵件的收件人不是自己卻收到了這封郵件,就是利用了暗抄這個屬性。 3.郵件體一般分為郵件正文本部分和附件部分。正文部分需要設置文本的格式,包括text文本類型,messafe報文類型,image圖象類型,video視頻類型,audio聲音類型,application應用程序類型,multipart混合類型等。如下例, String m_body; //為需要添加文本內容 MimeMultipart content=new MimeMultipart(); //創建郵件體對象 if(content==null) return false; MimeBodyPart part=new MimeBodyPart(); //創建文本部分對象 String type="text/plain"; //文本類型默認為text/plain if(m_body.startsWith("<html>") || m_body.startsWith("<HTML>")) type="text/html"; //如果是網頁形式的內容,則改變類型為text/html part.setText(m_body); part.setHeader("Content-Type",type); content.addBodyPart(part); msg.setContent(content); //添加文本至郵件中 msg.saveChanges(); //保存修改 4.如何向的郵件中添加附件,利用多用途互聯網郵件擴展(MIME)協議可以直接二進制數據添加到標準的RFC822郵件中。在JAVAMAIL中實現方法如下, String filename; //用于存儲文件名稱與存放路徑 if(filename!=null || filename.length()>0){ MimeBodyPart part=new MimeBodyPart();//創建MIME對象 DataSource fds = new FileDataSource(filename); //創建文件流對象 part.setDataHandler(new DataHandler(fds)); part.setFileName(MimeUtility.encodeText(fds.getName())); content.addBodyPart(part); //添加二進制編碼至郵件體中 } msg.setContent(content); //添加文本至郵件中 msg.saveChanges(); //保存修改 5.郵件的基本內容設置完畢,發送SMTP電子郵件。 Transport trans=sess.getTransport(); //創建發送對象 trans.send (msg); //發送 6.如何群發郵件,首先我們要有一個郵件地址列表,郵件地址列表可以向從公共網站獲得,也可以根據某單位名稱按字典法生成,或者購買用戶表。郵件地址列表應該按行存放每個郵件地址。 發信的速度和SMTP的響應速度有密切的關系,所以因該充分利用一封郵件可以有多個接受地址的條件,將郵件地址按組讀入進行發送,才能提高郵件群發地效率。下面的例子是每一封信發給10個郵件地址。 import java.io.*; import java.net.*; import java.util.*; import javax.mail.*; import javax.activation.*; import javax.mail.internet.*; class massmail(){ try{ FileReader fis = new FileReader(“郵件列表文件”); BufferedReader dis = new BufferedReader(fis); int i=0; while((fileline = dis.readLine())!=null){ if((i%10)==0) MimeMessage msg=new MimeMessage(sess); …… if((i%10)!=0){ //多個郵件地址之間要加“,” maillist = maillist + “,” + fileline; }else{ maillist = fileline; } i++; if((i%10)==0){ //一封郵件在暗抄地址處加10個收件人 msg.addRecipients(Message.RecipientType.BCC, maillist); …… //設置郵件內容 Transport trans=sess.getTransport(); //創建發送對象 trans.send (msg); //發送 } } fis.close(); }catch(Exception error){ System.out.println("Exception:" + error); } |
jwebee
我的個人網站