瘋狂java實(shí)例-第12章 郵件客戶(hù)端_第1頁(yè)
瘋狂java實(shí)例-第12章 郵件客戶(hù)端_第2頁(yè)
瘋狂java實(shí)例-第12章 郵件客戶(hù)端_第3頁(yè)
瘋狂java實(shí)例-第12章 郵件客戶(hù)端_第4頁(yè)
瘋狂java實(shí)例-第12章 郵件客戶(hù)端_第5頁(yè)
已閱讀5頁(yè),還剩37頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第12章 郵件客戶(hù)端在日常的生活中,我們都使用到許多的郵件客戶(hù)端,例如Foxmail、Outlook等,這些郵件客戶(hù)給我們收發(fā)郵件帶來(lái)了方便,不必再去打開(kāi)網(wǎng)頁(yè)去查看郵件,只打開(kāi)這些客戶(hù)端,就可以輕松的收發(fā)郵件。本章我們將介紹如何使用Java去開(kāi)發(fā)一款自己的郵件客戶(hù)端,功能并不需要太復(fù)雜,可以收發(fā)郵件,管理郵件即可,從這些功能中體會(huì)這些客戶(hù)端的原理。12.1 本章涉及的技術(shù)使用Java開(kāi)發(fā)郵件客戶(hù)端,首先想到的就是JavaMail API,另外,我們還需要對(duì)郵件進(jìn)行保存,例如像Foxmail一樣將郵件下載到本地的系統(tǒng)中,使用一些文件來(lái)對(duì)這些郵件進(jìn)行保存,這些做可以提高郵件客戶(hù)端的性能,不必每次都

2、上互聯(lián)網(wǎng)上去下載這些郵件,只需要通過(guò)操作本地系統(tǒng)中的文件就可以達(dá)到操作郵件的目的,為了滿(mǎn)足這個(gè)要求,我們還會(huì)使用XStream這個(gè)項(xiàng)目,下面先對(duì)JavaMail進(jìn)行簡(jiǎn)單的描述。12.1.1 JavaMail簡(jiǎn)介JavaMail API是Sun提供的處理電子郵件的API,可以方便的使用它來(lái)進(jìn)行一些常用的郵件操作,它提供了獨(dú)立于各個(gè)平臺(tái)和獨(dú)立于各種協(xié)議的框架,可以讓我們?nèi)?gòu)建一些郵件和消息的應(yīng)用。我們可以從以下網(wǎng)址得到JavaMail的包:/products/javamail/downloads/index.html本章中所使用的JavaMail版本為1.4.2

3、,下載了JavaMail后,將mail.jar加入項(xiàng)目的CLASS_PATH中,就可以使用JavaMail API。本章中使用了SMTP協(xié)議和POP3協(xié)議來(lái)進(jìn)行發(fā)送郵件和接收郵件,下面介紹這兩種協(xié)議。12.1.2 SMTP協(xié)議簡(jiǎn)介SMTP是Simple Mail Transfer Protocol的縮寫(xiě),譯為簡(jiǎn)單郵件傳輸協(xié)議,SMTP被用來(lái)在互聯(lián)網(wǎng)上傳遞各種電子郵件的協(xié)議,可以將郵件從本客戶(hù)端傳送到郵件服務(wù)器,簡(jiǎn)單的說(shuō),我們可以使用這個(gè)協(xié)議發(fā)送郵件。在一般的情況下,SMTP使用25作監(jiān)聽(tīng)端口。大部分的郵箱都支持這SMTP協(xié)議,例如Gmail的郵箱提供的SMTP服務(wù)器地址是:smtp.gmail

4、.com,如果我們需要使用我們的Gmail來(lái)發(fā)送郵件,就需要使用到這一個(gè)SMTP服務(wù)器地址。12.1.3 POP3協(xié)議簡(jiǎn)介POP3是Post Office Protocol的縮寫(xiě),即郵局協(xié)議,用于電子郵件的接收,一般情況下,它使用TCP的110端口,由于現(xiàn)在最常用的是第三版,因此稱(chēng)為POP3。簡(jiǎn)單的說(shuō),這個(gè)協(xié)議用于接收電子郵件,因此我們?cè)诒菊碌泥]件客戶(hù)端中,將會(huì)使用這個(gè)協(xié)議來(lái)接收郵件。12.1.4 XStream簡(jiǎn)介XStream是一個(gè)簡(jiǎn)單的Java庫(kù),它可以將Java對(duì)象轉(zhuǎn)換成XML,也可以將XML轉(zhuǎn)換成Java對(duì)象。在本章中,我們從遠(yuǎn)程的郵件服務(wù)器得到郵件后,需要下載到本地進(jìn)行保存,再將遠(yuǎn)

5、程郵件服務(wù)器中的郵件刪除,這樣當(dāng)我們?yōu)g覽郵件的時(shí)候,可以不必再?gòu)倪h(yuǎn)程的郵件服務(wù)器下載,提高了郵件客戶(hù)端的性能。由于本章中不涉及數(shù)據(jù)庫(kù)應(yīng)用,因此可以將郵件轉(zhuǎn)換成一些XML格式的文件,保存在本地系統(tǒng)中,每次操作郵件的時(shí)候,都可以對(duì)這些XML文件進(jìn)行操作,提高了郵件客戶(hù)端的性能。我們可以從下面的網(wǎng)址得到XStream:/download.html 本章中所使用的版本為1.3.1,下載后將lib下的xstream-1.3.1.jar包與xpp3_min-1.1.4c.jar的包加到項(xiàng)目的CLASS_PATH中即可使用XStream的API。JavaM

6、ail和XStream的使用將在以下章節(jié)介紹如何使用。12.2 建立界面在開(kāi)發(fā)郵件的主要功能前,我們先建立相關(guān)的界面。我們需要先確定要些什么界面,首先,當(dāng)然是需要一個(gè)進(jìn)入系統(tǒng)的界面(登錄),讓用戶(hù)去輸入用戶(hù)名,根據(jù)用戶(hù)名去建立與這個(gè)用戶(hù)名相關(guān)的用戶(hù)信息。接下來(lái),需要建立一個(gè)主界面,用來(lái)進(jìn)行查看郵件、發(fā)送郵件、接收郵件和處理郵件等操作,然后,還需要有一個(gè)配置界面,讓用戶(hù)去配置郵箱(用戶(hù)名和密碼)、SMTP協(xié)議和POP3協(xié)議等信息,最后,需要提供一個(gè)寫(xiě)郵件的界面,讓用戶(hù)去輸入郵件信息,并發(fā)送到具體的地址。12.2.1 登錄界面我們需要提供一個(gè)登錄界面,讓用戶(hù)確定用戶(hù)名,我們這里并不需要進(jìn)行密碼驗(yàn)證

7、,因?yàn)橛脩?hù)能否連入他的郵件,取決于對(duì)郵箱的配置。登錄界面如圖12.1所示。圖12.1 登錄界面登錄界面十分簡(jiǎn)單,一個(gè)輸入框和兩個(gè)按鈕就構(gòu)成了登錄界面,點(diǎn)擊取消就退出客戶(hù)端。該界面對(duì)應(yīng)的Java類(lèi)為項(xiàng)目中的LoginFrame。12.2.2 客戶(hù)端主界面客戶(hù)端的主界面需要進(jìn)行各種的郵件處理,因此界面相對(duì)較為復(fù)雜,主界面的最終效果如圖12.2所示。圖12.2 客戶(hù)端主界面圖12.2中客戶(hù)端的主界面中結(jié)構(gòu)較為復(fù)雜,圖12.2中的區(qū)域,是一棵導(dǎo)航樹(shù),點(diǎn)擊不同的鏈接,可以進(jìn)入到收件箱、發(fā)件箱、已發(fā)送、草稿箱和垃圾箱中,當(dāng)我們點(diǎn)擊導(dǎo)航樹(shù)上的各個(gè)節(jié)點(diǎn)時(shí),區(qū)域的列表就顯示不同類(lèi)型的郵件,當(dāng)我們點(diǎn)擊了區(qū)域列表中

8、的某一封郵件時(shí),郵件的主要信息就會(huì)顯示在區(qū)域,該郵件的附件就會(huì)顯示在區(qū)域,區(qū)域是一個(gè)工具條,存放對(duì)郵件的各個(gè)操作,該工具條所定義操作分別有(圖12.2的區(qū)域由左往右):q 收取郵件:到遠(yuǎn)程的郵件服務(wù)器中收取新收的郵件。q 發(fā)送郵件:當(dāng)用戶(hù)選擇了某一份在發(fā)件箱、已發(fā)送、草稿箱和垃圾箱的郵件時(shí),就彈出寫(xiě)郵件的界面,將選擇的郵件信息顯示到寫(xiě)郵件的界面。q 寫(xiě)郵件:彈出寫(xiě)郵件的界面,讓用戶(hù)編寫(xiě)郵件。q 回復(fù)郵件:當(dāng)用戶(hù)選擇了某一份郵件點(diǎn)擊回復(fù)時(shí),彈出寫(xiě)郵件的界面。q 轉(zhuǎn)發(fā)郵件:與回復(fù)郵件一樣,但是轉(zhuǎn)發(fā)時(shí)收信人為空。q 刪除郵件:將所選擇的郵件放到垃圾箱中。q 徹底刪除郵件:在本系統(tǒng)中徹底刪除該郵件,一

9、旦刪除,將不可被還原。q 還原郵件:將在垃圾箱中的郵件還原到原來(lái)的目錄。q 設(shè)置:配置用戶(hù)郵箱相關(guān)的信息,包括賬號(hào)、密碼、SMTP協(xié)議與POP3協(xié)議等。客戶(hù)端主界面對(duì)應(yīng)的類(lèi)為MainFrame。實(shí)現(xiàn)圖12.2的界面,需要注意的是導(dǎo)航樹(shù)的實(shí)現(xiàn),由于在外觀(guān)上這并不是一棵樹(shù),但在本章中使用了樹(shù),以下是導(dǎo)航樹(shù)的實(shí)現(xiàn)代碼,MainFrame的createTree方法。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiMainFrame.java/創(chuàng)建導(dǎo)航的樹(shù)private JTree createTree() /創(chuàng)建根節(jié)點(diǎn)DefaultMutableTreeNode root

10、= new DefaultMutableTreeNode();/加入各個(gè)子節(jié)點(diǎn)root.add(new DefaultMutableTreeNode(new InBox();root.add(new DefaultMutableTreeNode(new OutBox();root.add(new DefaultMutableTreeNode(new SentBox();root.add(new DefaultMutableTreeNode(new DraftBox();root.add(new DefaultMutableTreeNode(new DeletedBox();/創(chuàng)建樹(shù)JTree

11、tree = new JTree(root);/加入鼠標(biāo)監(jiān)聽(tīng)器tree.addMouseListener(new SailTreeListener(this);/隱藏根節(jié)點(diǎn)tree.setRootVisible(false);/設(shè)置節(jié)點(diǎn)處理類(lèi)SailTreeCellRenderer cellRenderer = new SailTreeCellRenderer();tree.setCellRenderer(cellRenderer);return tree;以上的代碼中,使用了五個(gè)Box的類(lèi):InBox、OutBox、SentBox、DraftBox和DeletedBox,這五個(gè)類(lèi)分別代碼著導(dǎo)

12、航樹(shù)中的五個(gè)不同鏈接。另外還有一個(gè)鼠標(biāo)監(jiān)聽(tīng)器類(lèi)和節(jié)點(diǎn)處理類(lèi),以下為五個(gè)Box類(lèi)的實(shí)現(xiàn)。代碼清單:codefoxmailsrcorgcrazyitfoxmailboxMailBox.javapublic interface MailBox /獲得box名字String getText();/返回對(duì)應(yīng)圖標(biāo)ImageIcon getImageIcon();再新建一個(gè)接象類(lèi),給五個(gè)Box類(lèi)去繼承。代碼清單:codefoxmailsrcorgcrazyitfoxmailboxAbstractBox.javapublic abstract class AbstractBox implements Mail

13、Box /該box所對(duì)應(yīng)的圖片(顯示在樹(shù)上的圖片)private ImageIcon icon;/實(shí)現(xiàn)接口的方法public ImageIcon getImageIcon(String imagePath) if (this.icon = null) this.icon = new ImageIcon(imagePath);return this.icon;/重寫(xiě)toString方法, 調(diào)用接口的getText方法, getText方法由子類(lèi)去實(shí)現(xiàn)public String toString() return getText();五個(gè)Box類(lèi)只需要去繼承AbstractBox并實(shí)現(xiàn)getTex

14、t方法即可,以下為InBox類(lèi)的實(shí)現(xiàn)。代碼清單:codefoxmailsrcorgcrazyitfoxmailboxInBox.javapublic class InBox extends AbstractBox public String getText() return 收件箱;public ImageIcon getImageIcon() return super.getImageIcon(images/in-tree.gif);InBox類(lèi)代表樹(shù)中的收件箱節(jié)點(diǎn),只需要返回文字與圖片即可。其他的四個(gè)Box類(lèi)與InBox實(shí)現(xiàn)一樣,這里不貼出代碼,具體可看本書(shū)所附的代碼。實(shí)現(xiàn)了五個(gè)Box后,

15、我們可以在樹(shù)中使用這五個(gè)Box,以下是導(dǎo)航樹(shù)的鼠標(biāo)事件監(jiān)聽(tīng)器類(lèi)。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiSailTreeListener.java public class SailTreeListener extends MouseAdapter private MainFrame mainFrame;public SailTreeListener(MainFrame mainFrame) this.mainFrame = mainFrame;public void mousePressed(MouseEvent e) /暫時(shí)提供空實(shí)現(xiàn)一個(gè)簡(jiǎn)單的監(jiān)聽(tīng)器類(lèi),

16、鼠標(biāo)的點(diǎn)擊方法沒(méi)有實(shí)現(xiàn),我們?cè)谙旅嬲鹿?jié)會(huì)提供實(shí)現(xiàn)。以下代碼是樹(shù)的節(jié)點(diǎn)處理類(lèi)SailTreeCellRenderer。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiSailTreeCellRenderer.javapublic class SailTreeCellRenderer extends DefaultTreeCellRenderer /樹(shù)節(jié)點(diǎn)被選中時(shí)的字體private Font selectFont;public SailTreeCellRenderer() this.selectFont = new Font(null, Font.BOLD, 12);

17、public Component getTreeCellRendererComponent(JTree tree, Object value,boolean sel, boolean expanded, boolean leaf, int row,boolean hasFocus) DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;MailBox box = (MailBox)node.getUserObject();this.setText(box.getText();/判斷是否選中, 再?zèng)Q定使用字體if (isSelec

18、ted(node, tree) this.setFont(this.selectFont);else this.setFont(null);/設(shè)置樹(shù)節(jié)點(diǎn)所顯示的圖標(biāo)this.setIcon(box.getImageIcon();return this;/判斷一個(gè)node是否被選中private boolean isSelected(DefaultMutableTreeNode node, JTree tree) /得到選中的TreePathTreePath treePath = tree.getSelectionPath();if (treePath = null) return false;

19、/得到被選中的節(jié)點(diǎn)DefaultMutableTreeNode selectNode = (DefaultMutableTreeNode)treePath.getLastPathComponent();/如果選中的節(jié)點(diǎn)與參數(shù)的節(jié)點(diǎn)一致, 那么意味著參數(shù)的節(jié)點(diǎn)被選中if (node.equals(selectNode) return true;return false;由于我們?cè)趧?chuàng)建樹(shù)節(jié)點(diǎn)的時(shí)候,使用的是五個(gè)Box作為DefaultMutableTreeNode的構(gòu)造參數(shù),因此,以上代碼的黑體部分,我們可以得到這些Box對(duì)象,而五個(gè)Box對(duì)象都是MailBox接口的實(shí)現(xiàn),因此只需要強(qiáng)制類(lèi)型轉(zhuǎn)換為

20、MailBox即可,根據(jù)得到的節(jié)點(diǎn)對(duì)應(yīng)的MailBox對(duì)象,可以獲得該Box對(duì)應(yīng)的圖片與文字,再設(shè)置到樹(shù)的節(jié)點(diǎn)中,最后判斷節(jié)點(diǎn)是否被選中,來(lái)設(shè)置不同的字體。以上為圖12.2中區(qū)域?qū)Ш綐?shù)的實(shí)現(xiàn),整個(gè)界面的布局可以使用JSplitPane來(lái)實(shí)現(xiàn),區(qū)域是一個(gè)JTable,區(qū)域是一個(gè)JList對(duì)象,區(qū)域是一個(gè)JTextArea對(duì)象并不可編輯,區(qū)域是一個(gè)JToolBar對(duì)象,區(qū)域的實(shí)現(xiàn)在這里不再詳細(xì)描述,請(qǐng)看代碼清單的codefoxmailsrcorgcrazyitfoxmailuiMainFrame.java。12.2.3 配置界面配置界面主要用來(lái)配置用戶(hù)的郵箱信息,包括郵箱賬號(hào)、密碼、SMTP服務(wù)器

21、、SMTP端口、POP3服務(wù)器和POP3端口,配置界面如圖12.3所示。圖12.3 配置界面該界面并沒(méi)有多復(fù)雜的結(jié)構(gòu),只是由幾個(gè)普通的JLabel與JTextField組成,當(dāng)用戶(hù)填寫(xiě)完相關(guān)的信息并點(diǎn)擊確定后,配置界面將關(guān)閉,一旦配置完后,整個(gè)客戶(hù)端將會(huì)以這些配置為依據(jù),去收取郵件或者發(fā)送郵件。在本章中,配置界面對(duì)應(yīng)的類(lèi)為SetupFrame。以下為在客戶(hù)端主界面(MainFrame)打開(kāi)配置界面的代碼。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiMainFrame.java/設(shè)置private Action setup = new AbstractAction

22、(設(shè)置, new ImageIcon(images/setup.gif) public void actionPerformed(ActionEvent e) setup();/設(shè)置方法, 打開(kāi)設(shè)置界面private void setup() if (this.setupFrame = null) this.setupFrame = new SetupFrame(this);this.setupFrame.setVisible(true);12.2.4 郵件編寫(xiě)界面最后來(lái)完成整個(gè)客戶(hù)端的最后一個(gè)界面:編寫(xiě)郵件界面。郵件編寫(xiě)界面并不復(fù)雜,只是提供一些JTextField和一個(gè)JTextArea來(lái)

23、讓用戶(hù)輸入相關(guān)的郵件信息,例如收件人、抄送、郵件主題、郵件內(nèi)容與附件,存放附件可以提供一個(gè)JList來(lái)實(shí)現(xiàn)。郵件編寫(xiě)界面如圖12.4所示。圖12.4 郵件編寫(xiě)界面圖12.4中的區(qū)域是郵件的附件存放區(qū)域,對(duì)應(yīng)一個(gè)JList對(duì)象,區(qū)域是郵件的正文區(qū)域,區(qū)域是一個(gè)JToolBar,可以對(duì)該封正在編寫(xiě)的郵件進(jìn)行一系列的操作,從左到右的操作分別為:q 發(fā)送:將郵件馬上發(fā)送到收件人中。q 保存至發(fā)件箱:將該封正在編寫(xiě)的郵件保存到發(fā)件箱中,等待下次操作再進(jìn)行發(fā)送。q 保存至草稿箱:將該封郵件保存到草稿箱中,可以作其他郵件的模板。q 增加附件:為正在編寫(xiě)的郵件增加一個(gè)附件,增加完后將在圖12.4的區(qū)域(JLi

24、st)中顯示。q 刪除附件:當(dāng)用戶(hù)在附件的列表中(JList)選擇了一份附件點(diǎn)擊刪除時(shí),該附件并從附件列表中刪除。郵件編寫(xiě)界面在本章中對(duì)應(yīng)的類(lèi)為MailFrame,整個(gè)界在的布局都可以使用JSplitPane來(lái)實(shí)現(xiàn),具體實(shí)現(xiàn)方式與主界面(MainFrame)的實(shí)現(xiàn)類(lèi)似,而且具體的操作也與主界面相似,當(dāng)用戶(hù)點(diǎn)擊了編寫(xiě)郵件的時(shí)候,就需要顯示該界面。以下為在主界面(MainFrame)中打開(kāi)郵件編寫(xiě)界面(MailFrame)的代碼。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiMainFrame.java/寫(xiě)郵件private Action write = new Ab

25、stractAction(寫(xiě)郵件, new ImageIcon(images/new.gif) public void actionPerformed(ActionEvent e) write();private void write() /編寫(xiě)郵件的界面對(duì)象mailFramethis.mailFrame.setVisible(true);到此,我們這個(gè)郵件客戶(hù)端的所有界面都已經(jīng)完成了,接下來(lái)我們開(kāi)始編寫(xiě)這個(gè)郵件客戶(hù)端的主體功能,包括保存用戶(hù)的配置、接收郵件、發(fā)送郵件和操作郵件等功能。12.3 創(chuàng)建客戶(hù)端的基礎(chǔ)對(duì)象接收郵件我們使用POP3協(xié)議,通過(guò)用戶(hù)配置的賬號(hào)和密碼,到遠(yuǎn)程的郵件服務(wù)器中下載

26、郵件,并顯示在收件箱的列表中,在做這些事前,我們需要將郵件的各個(gè)對(duì)象先準(zhǔn)備好,例如與郵箱相關(guān)的郵件上。除此之外還需要一個(gè)郵件的讀取接口,用于讀取郵件,由于我們使用JavaMail從郵件服務(wù)器得到的郵件對(duì)象是Message,因此該接口需要將Message轉(zhuǎn)換成Mail對(duì)象。12.3.1 創(chuàng)建郵箱上下文對(duì)象首先需要?jiǎng)?chuàng)建一個(gè)郵件上下文對(duì)象,用于保存郵條箱的連接信息,包括賬號(hào)、密碼、SMTP協(xié)議、SMTP端口、POP3協(xié)議和POP3端口,新建MailContext類(lèi),該類(lèi)在下面將會(huì)十分常用。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiMailContext.javapu

27、blic class MailContext /系統(tǒng)用戶(hù)private String user;/用戶(hù)帳號(hào)private String account;/密碼private String password;/smtp郵件服務(wù)器private String smtpHost;/smtp端口private int smtpPort;/pop3郵件服務(wù)器private String pop3Host;/pop3的端口private int pop3Port;/是否進(jìn)行重置信息private boolean reset = false;/省略各個(gè)屬性的setter和getter方法除了需要提供以上代碼

28、的屬性外,還需要提供一個(gè)JavaMail的Store對(duì)象,當(dāng)外界請(qǐng)求這個(gè)類(lèi)的時(shí)候,可以馬上返回這個(gè)Store對(duì)象,該對(duì)象代表郵箱的倉(cāng)儲(chǔ)。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiMailContext.javaprivate Store store;/返回Store對(duì)象public Store getStore() /重置了信息, 設(shè)置Store為nullif (this.reset) this.store = null;this.session = null;this.reset = false;if (this.store = null | !this.s

29、tore.isConnected() try Properties props = System.getProperties();/創(chuàng)建mail的SessionSession session = Session.getDefaultInstance(props, getAuthenticator();/使用pop3協(xié)議接收郵件URLName url = new URLName(pop3, getPop3Host(), getPop3Port(), null, getAccount(), getPassword();/得到郵箱的存儲(chǔ)對(duì)象Store store = session.getStore

30、(url);store.connect();this.store = store; catch (Exception e) e.printStackTrace();throw new MailConnectionException(連接郵箱異常,請(qǐng)檢查配置);return this.store;/將賬號(hào)與密碼封裝成一個(gè)JavaMail的Authenticator對(duì)象,表示需要經(jīng)過(guò)身份驗(yàn)證private Authenticator getAuthenticator() return new Authenticator() protected PasswordAuthentication getP

31、asswordAuthentication() return new PasswordAuthentication(getAccount(), getPassword();在這里外界可以通過(guò)一個(gè)getStore的方法得到Store對(duì)象,而且需要經(jīng)過(guò)判斷,如果當(dāng)Store對(duì)象為空或者沒(méi)有連接上的時(shí)候,就進(jìn)行Store對(duì)象的創(chuàng)建,這是由于Store對(duì)象創(chuàng)建需要連接到遠(yuǎn)程的郵件服務(wù)器,因此創(chuàng)建或者連接都需要等待較長(zhǎng)時(shí)間,而我們一旦配置好了之后,就無(wú)需每次都去創(chuàng)建,共用一個(gè)Stroe對(duì)象即可,這就好像JDBC中的Connection對(duì)象的創(chuàng)建一樣,創(chuàng)建一次Connection系統(tǒng)的開(kāi)銷(xiāo)都很大,只需要一

32、次創(chuàng)建,即可一直使用該實(shí)例。另外,我們還提供了一個(gè)reset的布爾值,表示該MailContext對(duì)象是否被更改過(guò),如果用戶(hù)重新設(shè)置了郵箱賬號(hào)、密碼等信息,那么就需要告訴MailContext,重新獲得Store對(duì)象。以上代碼中的黑體部分是使用JavaMail去連接郵箱。12.3.2 創(chuàng)建郵件對(duì)象在我們的客戶(hù)端中,需要提供一個(gè)Mail對(duì)象,在本系統(tǒng)中一個(gè)Mail對(duì)象代表一封郵件,Mail對(duì)象的各個(gè)屬性如下。代碼清單:codefoxmailsrcorgcrazyitfoxmailobjectMail.javapublic class Mail /在本地系統(tǒng)中代表該郵件的xml文件的名字, 使用U

33、UID作為文件名:uuid.xmlprivate String xmlName;/發(fā)送人private String sender;/收件人, 可以多個(gè)private List receivers;/郵件標(biāo)題private String subject;/日期private Date receiveDate;/郵件大小private String size;/是否已經(jīng)被閱讀private boolean hasRead;/郵件正文private String content;/抄送private List ccs;/附件private List files;/郵件來(lái)源, 如果是從郵箱收到的,

34、則放在INBOX, 其他情況對(duì)應(yīng)的放private String from;/省略setter和getter方法按照我們最初的要求,如果從遠(yuǎn)程的郵件服務(wù)器下載了郵件后,需要將郵件轉(zhuǎn)換成一份XML文件,因此這里的Mail對(duì)象就是我們需要轉(zhuǎn)換的對(duì)象,那么我們就需要為Mail對(duì)象提供一個(gè)xmlName的屬性,該屬性代表該Mail對(duì)象所對(duì)應(yīng)的XML文件的文件名,設(shè)置Mail的xmlName的屬性時(shí),該文件名必須是唯一的,因此需要使用UUID來(lái)生成。這個(gè)xmlName只是一個(gè)文件名,并不是XML文件的絕對(duì)路徑。在以上的代碼中,Mail對(duì)象還有一個(gè)files屬性,代表該郵件所對(duì)應(yīng)的所有附件,每一個(gè)附件在客

35、戶(hù)端中代表一個(gè)FileObject對(duì)象,以下是FileObject的屬性。代碼清單:codefoxmailsrcorgcrazyitfoxmailobjectFileObject.javapublic class FileObject /源文件名字private String sourceName;/對(duì)應(yīng)的文件private File file;/省略setter和getter方法FileObject只保存一個(gè)sourceName和一個(gè)File對(duì)象,sourceName表示用戶(hù)在上傳附件時(shí)的源文件的名稱(chēng),當(dāng)我們將文件保存在本地的時(shí)候,需要將附件重命名并以UUID作為這些文件的名稱(chēng),這樣做的話(huà)原

36、來(lái)文件的文件名將會(huì)丟失,因此需要使用sourceName來(lái)保存源文件的名字。以上為兩個(gè)在本章中最基礎(chǔ)的兩個(gè)對(duì)象,下面開(kāi)始實(shí)現(xiàn)登錄功能和用戶(hù)配置功能。12.4 用戶(hù)登錄與用戶(hù)配置在12.2.1和12.2.3中,我們提供了一個(gè)登錄界面和一個(gè)配置的界面,當(dāng)用戶(hù)進(jìn)行登錄時(shí),我們需要為這個(gè)用戶(hù)名創(chuàng)建一個(gè)具體的目錄,用來(lái)保存這個(gè)用戶(hù)的信息,例如該用戶(hù)所使用的配置、具體使用的郵箱等,如果一個(gè)用戶(hù)使用多個(gè)不同的郵箱,那么就需要在用戶(hù)對(duì)應(yīng)的目錄下再創(chuàng)建多個(gè)不同的賬號(hào)目錄,下面先來(lái)實(shí)現(xiàn)用戶(hù)登錄的功能。12.4.1 實(shí)現(xiàn)用戶(hù)登錄在本章中,用戶(hù)登錄并不需要進(jìn)行密碼驗(yàn)證,只需要用戶(hù)去確認(rèn)自己的用戶(hù)名,系統(tǒng)根據(jù)這個(gè)用戶(hù)去

37、創(chuàng)建或者定位到屬于該用戶(hù)的目錄。以下為L(zhǎng)oginFrame的確定方法。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiLoginFrame.javaprivate void confirm() /得到用戶(hù)名,可以在此加入驗(yàn)證,如果為空,則提示并返回String user = this.userField.getText();/得到用戶(hù)名對(duì)應(yīng)的目錄File folder = new File(FileUtil.DATE_FOLDER + user);/該用戶(hù)的目錄不存在,代表該用戶(hù)第一次進(jìn)入系統(tǒng),創(chuàng)建用戶(hù)目錄if (!folder.exists() folder.mk

38、dir();/得到配置文件File config = new File(folder.getAbsolutePath() + FileUtil.CONFIG_FILE);try /沒(méi)有對(duì)應(yīng)的配置文件,則創(chuàng)建if (!config.exists() config.createNewFile();/讀取配置并轉(zhuǎn)換為MailContext對(duì)象MailContext ctx = PropertiesUtil.createContext(config);/設(shè)置MailContext的user屬性ctx.setUser(user);/創(chuàng)建系統(tǒng)界面主對(duì)象this.mainFrame = new MainFr

39、ame(ctx);/顯示主界面this.mainFrame.setVisible(true);/隱藏登錄界面this.setVisible(false); catch (IOException e) throw new LoginException(配置文件錯(cuò)誤);在以上的代碼中,用戶(hù)點(diǎn)輸入用戶(hù)名并點(diǎn)擊確定進(jìn)行登錄,就執(zhí)行以上的confirm方法,先判斷該用戶(hù)是否第一次登錄,判斷標(biāo)準(zhǔn)為該用戶(hù)對(duì)應(yīng)的目錄是否存在,再獲得該用戶(hù)的配置文件,再將配置文件里面的內(nèi)容(MailContext中的屬性)轉(zhuǎn)換成MailContext對(duì)象,再顯示主界面對(duì)象。代碼中使用了PropertiesUtil類(lèi)進(jìn)行創(chuàng)建Ma

40、ilContext對(duì)象,同時(shí)也使用了FileUtil的幾個(gè)常量,以下是PropertiesUtil的實(shí)現(xiàn)。代碼清單:codefoxmailsrcorgcrazyitfoxmailutilPropertiesUtil.javapublic class PropertiesUtil /根據(jù)文件得到Properties對(duì)象private static Properties getProperties(File propertyFile) throws IOException Properties prop = new Properties();FileInputStream fis = new Fi

41、leInputStream(propertyFile);prop.load(fis);return prop;/根據(jù)配置文件的對(duì)象來(lái)構(gòu)造MailContext對(duì)象public static MailContext createContext(File propertyFile) throws IOException Properties props = getProperties(propertyFile);/如果沒(méi)有配置smtp的端口,則使用默認(rèn)的25端口Integer smtpPort = getInteger(props.getProperty(smtpPort), 25);/如果沒(méi)有配

42、置pop3的端口,則使用默認(rèn)的110端口Integer pop3Port = getInteger(props.getProperty(pop3Port), 110);return new MailContext(null, props.getProperty(account), props.getProperty(password), props.getProperty(smtpHost), smtpPort, props.getProperty(pop3Host), pop3Port);/將參數(shù)s轉(zhuǎn)換成一個(gè)Integer對(duì)象,該字符串為空則返回參數(shù)中的默認(rèn)值private static I

43、nteger getInteger(String s, int defaultValue) if (s = null | s.trim().equals() return defaultValue;return Integer.parseInt(s);|PropertiesUtil將用戶(hù)配置文件中的幾個(gè)屬性讀取,并封裝成一個(gè)MailContext對(duì)象返回,以下是FileUtil的幾個(gè)常量。代碼清單:codefoxmailsrcorgcrazyitfoxmailutilFileUtil.javapublic class FileUtil /存放所有用戶(hù)數(shù)據(jù)的目錄public static fin

44、al String DATE_FOLDER = datas + File.separator;/存放具體某個(gè)用戶(hù)配置的properties文件public static final String CONFIG_FILE = File.separator + perties;實(shí)現(xiàn)以上的代碼后,運(yùn)行程序,輸入用戶(hù)名進(jìn)行登錄,可以看到項(xiàng)目下有一個(gè)data目錄,該目錄下就有一個(gè)用戶(hù)目錄,用戶(hù)目錄并且存在于一份perties的配置文件,由于現(xiàn)在沒(méi)有任何的配置,因此perties文件的內(nèi)容為空。這樣,用戶(hù)登錄的功能就已實(shí)現(xiàn),接下為我們?yōu)閜er

45、ties的添加內(nèi)容(用程序添加),對(duì)用戶(hù)的郵箱進(jìn)行配置。12.4.2 實(shí)現(xiàn)用戶(hù)信息配置在12.2.3中,已新建了一個(gè)用戶(hù)的配置界面,并且描述了如何從主界面進(jìn)入,如果用戶(hù)是第一次進(jìn)入配置界面,那么各個(gè)配置信息都是空的,如果不是第一次進(jìn)入該界面,那么就需要將以前所配置的信息傳遞給該界面(SetupFrame),可以為MainFrame提供一個(gè)getMailContext的方法,將對(duì)應(yīng)的MailContext對(duì)象傳給SetupFrame,注意,當(dāng)客戶(hù)端啟動(dòng)的時(shí)候,只能有一個(gè)郵箱上下文,即只能存在一個(gè)MailContext對(duì)象。以下是SetupFrame中初始化各個(gè)配置的代碼。代碼清單:codefox

46、mailsrcorgcrazyitfoxmailuiSetupFrame.java/初始化各個(gè)配置this.accountField.setText(ctx.getAccount();this.passwordField.setText(ctx.getPassword();this.smtpField.setText(ctx.getSmtpHost();this.pop3Field.setText(ctx.getPop3Host();this.smtpPortField.setText(String.valueOf(ctx.getSmtpPort();this.pop3PortField.se

47、tText(String.valueOf(ctx.getPop3Port();SetupFrame在構(gòu)造的時(shí)候,就需要根據(jù)MainFrame傳遞過(guò)來(lái)的MailContext去初始化各個(gè)界面組件的值。當(dāng)用戶(hù)輸入了各個(gè)信息后,我們就需要將這些配置信息保存到該用戶(hù)的配置文件中(即12.4.1中的perties)。以下為SetupFrame部分代碼。代碼清單:codefoxmailsrcorgcrazyitfoxmailuiSetupFrame.java/確定按鈕private void confirm() try /重新設(shè)置系統(tǒng)上下文的信息MailContext ctx = getM

48、ailContext(this.mainFrame.getMailContext();/設(shè)置已經(jīng)對(duì)信息進(jìn)行了重新設(shè)定ctx.setReset(true);/將新的上下文寫(xiě)入配置文件中PropertiesUtil.store(ctx);/設(shè)置主界面的MailContext對(duì)象this.mainFrame.setMailContext(ctx);/創(chuàng)建存放郵件的目錄(并非用戶(hù)的目錄, 一個(gè)用戶(hù)可能有多個(gè)郵箱地址)FileUtil.createFolder(ctx);this.setVisible(false); catch (Exception e) JOptionPane.showConfirm

49、Dialog(this, e.getMessage(), 警告, JOptionPane.OK_CANCEL_OPTION);/根據(jù)界面的值封裝MailContextprivate MailContext getMailContext(MailContext ctx) /省略從界面得到各個(gè)值,設(shè)置MailContext的各個(gè)屬性ctx.setAccount(account);ctx.setPassword(password);ctx.setSmtpHost(smtpHost);ctx.setSmtpPort(smtpPort);ctx.setPop3Host(pop3Host);ctx.set

50、Pop3Port(pop3Port);/由于重新設(shè)置了連接信息, 因此設(shè)置MailContext的reset值為truectx.setReset(true);return ctx;用戶(hù)輸入了界面中各個(gè)組件的值點(diǎn)擊確定后,直接調(diào)用以上的confirm方法,confirm方法調(diào)用getMailContext方法來(lái)設(shè)置MailContext的各個(gè)屬性。在這里需要注意的是,由于重新設(shè)置了MailContext的各個(gè)屬性,因此需要告訴MailContext用戶(hù)更新了配置(設(shè)置reset值為true),那么用戶(hù)在下次接收郵件的時(shí)候(即調(diào)用getStore方法),就可以使用新的配置來(lái)重新得到Store對(duì)象。

51、以上的代碼中使用PorpertiesUtil與FileUtil的兩個(gè)方法,下面是這兩個(gè)方法的實(shí)現(xiàn)。代碼清單:codefoxmailsrcorgcrazyitfoxmailutilPropertiesUtil.java/保存一個(gè)MailContext對(duì)象, 將它的屬性寫(xiě)入文件中public static void store(MailContext ctx) /得到配置文件pertiesFile propFile = new File(FileUtil.DATE_FOLDER + ctx.getUser() + FileUtil.CONFIG_FILE);Properties p

52、rop = getProperties(propFile);/省略設(shè)置各個(gè)屬性的代碼/寫(xiě)入配置文件FileOutputStream fos = new FileOutputStream(propFile);prop.store(fos, These are mail configs.);fos.close();代碼清單:codefoxmailsrcorgcrazyitfoxmailutilFileUtil.java/收件箱的目錄名public static final String INBOX = inbox;/發(fā)件箱的目錄名public static final String OUTBOX

53、= outbox;/已發(fā)送的目錄名public static final String SENT = sent;/草稿箱的目錄名public static final String DRAFT = draft;/垃圾箱的目錄名public static final String DELETED = deleted;/附件的存放目錄名public static final String FILE = file;/創(chuàng)建用戶(hù)的帳號(hào)目錄和相關(guān)的子目錄public static void createFolder(MailContext ctx) String accountRoot = getAccountRoot(ctx);/使用用戶(hù)當(dāng)前設(shè)置的帳號(hào)來(lái)生成目錄, 例如一個(gè)用戶(hù)叫user1, /有一個(gè)郵件賬號(hào)是那么將會(huì)在datas/user1/下生成一個(gè)目錄mkdir(new File(accountRoot);mkdir(ne

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論