一個web版outlook的實現

原文地址:http://write.blog.csdn.net/postedit

 

該系統實現類型outlook的功能,能將用戶各個郵箱的郵件及時的同步並整理,同時可以通過用戶設置的發送郵箱在系統進行發送郵件

 

系統組件

1. EmailSelecter

2.Sender

 

一.EmailSelecter組件 

   主要負責拉取郵件服務器上的郵件列表數據,採用模板模式,EmailSelecter是抽象模板類,抽象了拉取的各個步驟(模板方法)

   

   package com.platform.util.mail;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.text.SimpleDateFormat;

import java.util.ArrayList;

import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Properties;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

import javax.mail.Address;

import javax.mail.BodyPart;

import javax.mail.Flags;

import javax.mail.Flags.Flag;

import javax.mail.Folder;

import javax.mail.Message;

import javax.mail.MessagingException;

import javax.mail.Multipart;

import javax.mail.Part;

import javax.mail.Session;

import javax.mail.Store;

import javax.mail.URLName;

import javax.mail.internet.InternetAddress;

import javax.mail.internet.MimeMessage;

import javax.mail.internet.MimeMultipart;

import javax.mail.internet.MimeUtility;

 

import org.apache.commons.io.FilenameUtils;

import org.apache.commons.lang.StringUtils;

import org.apache.commons.mail.util.MimeMessageParser;

 

import sun.misc.BASE64Decoder;

import com.platform.oa.commange.mail.pojo.NetworkReceiverEmail;

import com.platform.oa.commange.mail.pojo.UserEmailAccount;

import com.platform.util.common.StringUtil;

import com.platform.util.constants.Constants;

import com.sun.mail.pop3.POP3Folder;

import common.Logger;

/**

 *

 * ========================================================

*  上海建業信息科技有限公司  研發中心

*  日  期:2015 -4- 21 下午3:14:52

*  作  者:姚金權

*  版  本:1.0

*  功能描述:遠程郵件查詢器

*

*  修訂日期                  修訂人              描述

*  2015-4 -21      姚金權           創建

* ========================================================

 */

public abstract class EmailSelecter {

       

       

        private static final Logger logger = Logger. getLogger(EmailSelecter.class);

       

        // 定義一個郵箱地址的正則表達式:姓名<郵箱>

    private static final Pattern pattern = Pattern. compile("(.+)(<.+@.+..+>)");

 

        /**

        *    

        * @Description: 根據成員變量 構造一個郵件鏈接 

        * @param   

        * @return URLName 

        * @author 姚金權

        * @since 2015- 4-17 下午6:13:36   

        * @throws

        */

    public abstract URLName initURL();

    /**

     *

     * @Description: 初始化配置信息 

     * @param   

     * @return void 

     * @author 姚金權

     * @since 2015- 4-17 下午6:14:35      

     * @throws

     */

    public abstract void initProperties(Properties props)throws Exception;

 

    /**

     *

     * @Description: 鏈接郵箱 

     * @param   

     * @return Store 

     * @author 姚金權

     * @since 2015- 4-17 下午6:12:33      

     * @throws

     */

    public Store conectStore() throws Exception{

        // 準備連接服務器的會話信息

        Properties props = new Properties();

        initProperties(props);

        URLName urln = initURL();

        Session session = Session. getInstance(props, null);

        Store store = session.getStore(urln);

        store.connect();

        return store;

    }

    /**

     *

     * @Description:接收郵件  

     * @param   

     * @return InboxSelectResult 

     * @author 姚金權

     * @since 2015- 4-21 下午3:15:19      

     * @throws

     */

    public  InboxSelectResult receive(UserEmailAccount account, int selectSize,String rootPath) throws Exception {

       Store store = conectStore();

        // 獲得收件箱

        Folder folder = store.getFolder( "INBOX");        

        // Folder.READ_ONLY:只讀權限  Folder.READ_WRITE:可讀可寫(可以修改郵件的狀態)

        folder.open(Folder. READ_WRITE); //打開收件箱  

        InboxSelectResult result = new InboxSelectResult();

        result.setCount(folder.getMessageCount());

        result.setNewCount(folder.getNewMessageCount());

        result.setUnreadCount(folder.getUnreadMessageCount());

        result.setDeletedCount(folder.getDeletedMessageCount());

        int count = folder.getMessageCount();

        if(count < 1){

               return result;

        }

        if(selectSize>count){

              selectSize =count;

        }

        int startIndex = (folder.getMessageCount()-selectSize)+1;

        int endIndex = folder.getMessageCount();

        // 得到收件箱中的所有郵件,並解析

        Message[] messages = folder.getMessages(startIndex, endIndex);

       

        result.setEmails(parseMessage(messages,folder,rootPath));

       

        //釋放資源

        folder.close( true);

        store.close();

        return result;

    }

   

   

    /**

     *

     * @Description:得到包含中文的地址  

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:15:38      

     * @throws

     */

    public  String getChineseAddress(String address){

       try{

        if(StringUtils.isEmpty(address)){

               return "" ;

        }            

       if(address.startsWith( "=?GB")||address.startsWith("=?gb" )){

              address=MimeUtility. decodeText(address);

       } else{

              address=toChinese(address);

       }

       } catch(Exception e){

          e.printStackTrace();

       }

       return address;

       }

    /**

     *

     * @Description:  

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:16:24      

     * @throws

     */

    public  String toChinese(String strvalue){

       try{

       if(strvalue== null)

       return null;

       else{

       strvalue = new String(strvalue.getBytes("ISO8859_1" ), "UTF-8" );

       return strvalue;

       }

       } catch(Exception e){

       return null;

       }

    }

    /**

     *

     * @Description: 得到base64加密地址 

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:16:15      

     * @throws

     */

    public  String getFromBASE64(String s) {

       if (s == null) return null;

       BASE64Decoder decoder = new BASE64Decoder();

       try {

       byte[] b = decoder.decodeBuffer(s);

       return new String(b);

       } catch (Exception e) {

       return null;

       }

    }

    /**

     * @throws MessagingException

     *

     * @Description:判斷郵件是否已讀  

     * @param   

     * @return boolean 

     * @author 姚金權

     * @since 2015- 4-16 下午7:04:20      

     * @throws

     */

    public boolean isReaded(Message message) throws MessagingException{

       boolean isRead = false;

       Flags flags = message.getFlags();

       if(flags.contains(Flags.Flag. SEEN)){

              isRead = true;

       }

       return isRead;

    }

   

    /**

     * @throws Exception

     *

     * @Description: 標記遠端郵件 

     * @param   

     * @return void 

     * @author 姚金權

     * @since 2015- 4-8 下午3:25:48

     * @throws

     */

    public  void markMail(String[] uuids,int startIndex,int endIndex,Flag flag) throws Exception{

       Store store = conectStore();

        // 獲得收件箱

        Folder folder = store.getFolder( "INBOX");      

        // Folder.READ_ONLY:只讀權限  Folder.READ_WRITE:可讀可寫(可以修改郵件的狀態)

        folder.open(Folder. READ_WRITE); //打開收件箱  

        Message[] messages = folder.getMessages(startIndex, endIndex);

       

        Map<String,Message> msgMap = new HashMap<String,Message>();

        for(Message message:messages){

              MimeMessage msg =(MimeMessage)message;

              msgMap.put(getUID(folder, msg), message);

        }

        for(String id:uuids){

              Message m = msgMap.get(id);

               if(m!=null ){

                     m.setFlag(flag, true);

              }

        }

        folder.close( true);

        store.close();

    }

   

    /**

     *

     * @Description: 刪除遠端服務器上的郵件 

     * @param   

     * @return void 

     * @author 姚金權

     * @since 2015- 4-8 下午3:51:41

     * @throws

     */

    public  void delMail(String[] uuids,int startIndex,int endIndex) throws Exception{

       markMail(uuids, startIndex, endIndex, Flag. DELETED);

    }

   

    /**

     * @throws Exception

     *

     * @Description: 標記遠端郵件爲已讀 

     * @param   

     * @return void 

     * @author 姚金權

     * @since 2015- 4-8 下午3:52:22

     * @throws

     */

    public  void markReaded(String[] uuids,int startIndex,int endIndex) throws Exception{

       markMail(uuids, startIndex, endIndex, Flag. SEEN);

    }

 

   

   

   

   

    public  void out(MimeMessage msg,Folder folder)throws MessagingException, IOException{

        System. out.println("------------------解析第" + msg.getMessageNumber() + "封郵件-------------------- " );

        System. out.println("發件人: " + getFrom(msg));

        System. out.println("發送時間:" + getSentDate(msg, null));

        System. out.println("是否已讀:" + isSeen(msg));

        System. out.println("郵件優先級:" + getPriority(msg));

        System. out.println("是否需要回執:" + isReplySign(msg));

        System. out.println("郵件ID:" +getUID(folder,msg));

        System. out.println("主題: " + getSubject(msg));

        System. out.println("編碼:" +msg.getEncoding());

        System. out.println("收件人:" + getReceiveAddress(msg));

        System. out.println("郵件大小:" + msg.getSize() * 1024 + "kb");

       

        boolean isContainerAttachment = isContainAttachment(msg);

        System. out.println("是否包含附件:" + isContainerAttachment);

        if (isContainerAttachment) {

//            saveAttachment( msg, "c:\\mailtmp \\"+msg.getSubject() + "_"); //保存附件

        } 

        StringBuffer content = new StringBuffer();

        getMailTextContent(msg, content);

       

        System. out.println("郵件正文:" + (content.length() > 100 ? content.substring(0,100) + "..." : content));

        System. out.println("------------------第" + msg.getMessageNumber() + "封郵件解析結束-------------------- " );

        System. out.println();

 

    }

    /**

     *

     * @Description: 得到郵件內容 

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-3 下午3:09:15

     * @throws

     */

    public  String getContext(MimeMessage msg) throws MessagingException, IOException{

       StringBuffer content = new StringBuffer();

       

        getMailTextContent(msg, content);

        String s = content.toString();

//        s= (s.length() > 100 ? s.substring(0,100) + "..." : s);

        return s;

    }

    /**

     * 解析郵件

     * @param messages 要解析的郵件列表

     */

    public  List<NetworkReceiverEmail> parseMessage(Message[] messages,Folder folder,String rootPath) throws MessagingException, IOException {

        if (messages == null || messages.length < 1){

               throw new MessagingException("未找到要解析的郵件!");

        } 

           

        List<NetworkReceiverEmail> receiverEmails = new ArrayList<NetworkReceiverEmail>();

        for (int i = 0, count = messages.length; i < count; i++) {

              NetworkReceiverEmail receiverEmail = new NetworkReceiverEmail();

            MimeMessage msg = (MimeMessage) messages[i];

            MimeMessageParser parser = null;

                      try {

                           parser = new MimeMessageParser(msg).parse();

                     } catch (Exception e) {

                           e.printStackTrace();

                     }

            receiverEmail.setSubject(getSubject(msg));

            receiverEmail.setFromAddress(getFrom(msg));

            receiverEmail.setToAddresses(getReceiveAddress(msg));

            receiverEmail.setCcAddresses(getCcAddress(msg));

            receiverEmail.setContent(getContext(msg));

          

            receiverEmail.setIsContainerAttachment(isContainAttachment(msg));

            receiverEmail.setIsReplySign(isReplySign(msg));

            receiverEmail.setEmailKey(getUID(folder,msg));

            String htmlContentString = getHtmlContent(parser);

            System. out.println("htmlContentString:" +htmlContentString);

           

            receiverEmail.setContentText(htmlContentString);

            receiverEmail.setSummary(getSummary(htmlContentString));

            receiverEmail.setSendTime(getSentDate(msg));

            receiverEmail.setStatus(isReaded(msg)?Constants.EMAIL_STATE_READED:Constants.EMAIL_STATE_NOREADED);

            receiverEmail.setPriority(getPriority(msg));

            //            String attPath = "";

            if(isContainAttachment(msg)){

              List<com.platform.system.upload.pojo.Attachment> attachments = new ArrayList<com.platform.system.upload.pojo.Attachment>();

              saveAttachment(msg, attachments,rootPath);

              receiverEmail.setAttachmentList(attachments);

            }

           

            receiverEmails.add(receiverEmail);

//            out( msg, folder);

        }

        return receiverEmails;

    }

    /**

     *

     * @Description: 得到遠程郵件的唯一標示 

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:18:04      

     * @throws

     */

    public abstract String getUID(Folder folder,MimeMessage msg)throws MessagingException;

   

    /**

     * 

     * @Description:得到郵件html內容  

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:17:43      

     * @throws

     */

    public  String getHtmlContent(MimeMessageParser parser){

       if(parser == null){

               return null ;

       }

       return parser.getPlainContent();

    }

    /**

     *

     * @Description: 得到摘要信息 

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:17:17      

     * @throws

     */

    public  String getSummary(String content){

       if(content == null){

               return null ;

       }

       content = StringUtil. htmlToText(content);

       String s= (content.length() > 50 ? content.substring(0,50) : content);

       return s;

    }

    /**

     *

     * @Description: 解決內容亂碼問題 

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:18:35      

     * @throws

     */

    public  String emailDecode(String encode,String text) throws UnsupportedEncodingException{

       String subject = text;

       if(encode != null && ("quoted-printable" .equals(encode) || "base64".equals(encode))){

              subject = MimeUtility. decodeText(text);

       }

       

           if(java.nio.charset.Charset.forName("iso-8859-1" ).newEncoder().canEncode(text)){

              subject   =textDecode(text);

       }

       return subject;

    }

    /**

     * 獲得郵件主題

     * @param msg 郵件內容

     * @return 解碼後的郵件主題

     * @throws IOException

     */

    public  String getSubject(MimeMessage msg) throws MessagingException, IOException {

       String encode = msg.getEncoding();

       String subject = msg.getSubject();

       return emailDecode(encode,subject);

    }

   

   

   

    public  String textDecode(String text){

       String result = null;

       try {

                      result = new String(text.getBytes("ISO8859-1" ),"GB2312" );

              } catch (UnsupportedEncodingException e) {

                      // TODO Auto-generated catch block

                     e.printStackTrace();

              }

       return result;

    }

   

    private  enum CodecType {

        ENCODE, DECODE

    }

   

    private  String codec(CodecType codecType, String address) {

        // 需要對滿足匹配條件的郵箱地址進行 UTF-8 編碼,否則姓名將出現中文亂碼

        Matcher addressMatcher = pattern.matcher(address);

        if (addressMatcher.find()) {

            try {

                if (codecType == CodecType.ENCODE) {

                    address = MimeUtility. encodeText(addressMatcher.group(1), "UTF-8", "B" ) + addressMatcher.group(2);

                } else {

                    address = MimeUtility. decodeText(addressMatcher.group(1)) + addressMatcher.group(2);

                }

            } catch (UnsupportedEncodingException e) {

                logger.error("錯誤:郵箱地址編解碼出錯!" , e);

            }

        }

        return address;

    }

   

 

    // 解碼郵箱地址

    public  String decodeAddress(String address) {

        return codec(CodecType.DECODE, address);

    }

   

        private  String[] doParse(Address[] addressList) {

               List<String> list = new ArrayList<String>();

               if (addressList != null && addressList.length>0 ) {

                   for (Address address : addressList) {

                       list.add(decodeAddress(address.toString()));

                   }

               }

               return list.toArray(new String[0]);

           }

   

    /**

     * 獲得郵件發件人

     * @param msg 郵件內容

     * @return 姓名 <Email地址>

     * @throws MessagingException

     * @throws UnsupportedEncodingException

     */

    public  String getFrom(MimeMessage msg) throws MessagingException, UnsupportedEncodingException {

        Address[] froms = msg.getFrom();

        String[] fromPerson = doParse(froms);

        if (froms.length < 1)

            throw new MessagingException("沒有發件人!");

         String encode = msg.getEncoding();

         String text = fromPerson[0];

         return emailDecode(encode, text);

    }

    /**

     * @throws UnsupportedEncodingException

     *

     * @Description: 得到收件人地址 

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-3 下午3:03:12

     * @throws

     */

    public  String getReceiveAddress(MimeMessage message) throws MessagingException, UnsupportedEncodingException{

       return getAddress(message, Message.RecipientType. TO);

    }

    /**

     * @throws UnsupportedEncodingException

     *

     * @Description:   得到抄送地址

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-3 下午3:04:56

     * @throws

     */

    public  String getCcAddress(MimeMessage message) throws MessagingException, UnsupportedEncodingException{

       return getAddress(message,Message.RecipientType. CC);

    }

    

    /**

     * 根據收件人類型,獲取郵件收件人、抄送和密送地址。如果收件人類型爲空,則獲得所有的收件人

     * <p>Message.RecipientType.TO  收件人</p>

     * <p>Message.RecipientType.CC  抄送</p>

     * <p>Message.RecipientType.BCC 密送</p>

     * @param msg 郵件內容

     * @param type 收件人類型

     * @return 收件人1 <郵件地址1> , 收件人2 <郵件地址2>, ...

     * @throws MessagingException

     * @throws UnsupportedEncodingException

     */

    public  String getAddress(MimeMessage msg, Message.RecipientType type) throws MessagingException, UnsupportedEncodingException {

        StringBuffer receiveAddress = new StringBuffer();

        Address[] addresss = null;        

        addresss = msg.getRecipients(type);

      

        if (addresss == null || addresss.length < 1){

               return receiveAddress.toString();

        }

           for (Address address : addresss) {

                   InternetAddress JepEmailInternetAddress = (InternetAddress)address;

                   receiveAddress.append(JepEmailInternetAddress.toUnicodeString()).append(",");

        }

        

//        receiveAddress.deleteCharAt(receiveAddress.length()-1); //刪除最後一個逗號

//     

           String encode = msg.getEncoding();

        String addressString = receiveAddress.toString();

////        return MimeUtility.decodeText(addressString);

        System. out.println("encode:" +encode+"text:" +addressString);

        addressString = new String(addressString.getBytes("gbk" ),"GB2312" );

        return addressString;

    }

    

    /**

     * 獲得郵件發送時間

     * @param msg 郵件內容

     * @return yyyymmdd 日 星期X HH:mm

     * @throws MessagingException

     */

    public  String getSentDate(MimeMessage msg, String pattern) throws MessagingException {

        Date receivedDate = msg.getSentDate();

        if (receivedDate == null)

            return "" ;

        

        if (pattern == null || "".equals(pattern))

            pattern = "yyyy年MM月dd日 E HH:mm " ;

        

        return new SimpleDateFormat(pattern).format(receivedDate);

    }

   

    public  Date getSentDate(MimeMessage msg) throws MessagingException {

        return  msg.getSentDate();

       

    }

    

    /**

     * 判斷郵件中是否包含附件

     * @param msg 郵件內容

     * @return 郵件中存在附件返回true,不存在返回false

     * @throws MessagingException

     * @throws IOException

     */

    public  boolean isContainAttachment(Part part) throws MessagingException, IOException {

        boolean flag = false ;

        if (part.isMimeType("multipart/*" )) {

            MimeMultipart multipart = (MimeMultipart) part.getContent();

            int partCount = multipart.getCount();

            for (int i = 0; i < partCount; i++) {

                BodyPart bodyPart = multipart.getBodyPart(i);

               

               

                String disp = bodyPart.getDisposition();

                if (disp != null && (disp.equalsIgnoreCase(Part. ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE ))) {

                    flag = true;

                } else if (bodyPart.isMimeType("multipart/*")) {

                    flag = isContainAttachment(bodyPart);

                } else {

                    String contentType = bodyPart.getContentType();

                    if (contentType.indexOf("application" ) != -1) {

                        flag = true;

                    }  

                    

                    if (contentType.indexOf("name" ) != -1) {

                        flag = true;

                    } 

                }

                

                if (flag) break ;

            }

        } else if (part.isMimeType("message/rfc822")) {

            flag = isContainAttachment((Part)part.getContent());

        }

        return flag;

    }

    

    /**

     * 判斷郵件是否已讀 

     * @param msg 郵件內容

     * @return 如果郵件已讀返回true,否則返回false

     * @throws MessagingException 

     */

    public  boolean isSeen(MimeMessage msg) throws MessagingException {

        return msg.getFlags().contains(Flags.Flag.SEEN);

    }

    

    /**

     * 判斷郵件是否需要閱讀回執

     * @param msg 郵件內容

     * @return 需要回執返回true,否則返回false

     * @throws MessagingException

     */

    public  boolean isReplySign(MimeMessage msg) throws MessagingException {

        boolean replySign = false;

        String[] headers = msg.getHeader( "Disposition-Notification-To");

        if (headers != null)

            replySign = true;

        return replySign;

    }

    

    /**

     * 獲得郵件的優先級

     * @param msg 郵件內容

     * @return 1(High):緊急  3:普通(Normal)  5:低(Low)

     * @throws MessagingException

     */

    public  int getPriority(MimeMessage msg) throws MessagingException {

        int priority = 0;

        String[] headers = msg.getHeader( "X-Priority");

        if (headers != null) {

            String headerPriority = headers[0];

            if (headerPriority.indexOf("1" ) != -1 || headerPriority.indexOf("High" ) != -1)

                priority = 1;

            else if (headerPriority.indexOf("5") != -1 || headerPriority.indexOf("Low" ) != -1)

                priority = 5;

            else

                priority = 3;

        }

        return priority;

    } 

    

    public  String getMailContent2(Part part) throws Exception{

         String contenttype=part.getContentType();

         StringBuffer bodytext = new StringBuffer();

         int nameindex=contenttype.indexOf("name" );

         boolean conname=false ;

         if(nameindex!=-1)conname=true;

         if(part.isMimeType("text/plain" )&&!conname){

          bodytext.append((String)part.getContent());  

         } else if (part.isMimeType("text/html")&&!conname){

          bodytext.append((String)part.getContent());  

         }

         else if (part.isMimeType("multipart/*")){

          Multipart multipart=(Multipart)part.getContent();

          int counts=multipart.getCount();

          for(int i=0;i<counts;i++){

           getMailContent2(multipart.getBodyPart(i));

          }

         } else if (part.isMimeType("message/rfc822")){

          getMailContent2((Part)part.getContent());

         }

         else{}

         return bodytext.toString();

        }

    /**

     * 獲得郵件文本內容

     * @param part 郵件體

     * @param content 存儲郵件文本內容的字符串

     * @throws MessagingException

     * @throws IOException

     */

    public  void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException {

        //如果是文本類型的附件,通過getContent方法可以取到文本內容,但這不是我們需要的結果,所以在這裏要做判斷

        boolean isContainTextAttach = part.getContentType().indexOf("name") > 0; 

        if (part.isMimeType("text/*" ) && !isContainTextAttach) {

            content.append(part.getContent().toString());

        } else if (part.isMimeType("message/rfc822")) { 

            getMailTextContent((Part)part.getContent(),content);

        } else if (part.isMimeType("multipart/*")) {

            Multipart multipart = (Multipart) part.getContent();

            int partCount = multipart.getCount();

            for (int i = 0; i < partCount; i++) {

                BodyPart bodyPart = multipart.getBodyPart(i);

                getMailTextContent(bodyPart,content);

            }

        }

    }

    

    /**

     * 保存附件

     * @param part 郵件中多個組合體中的其中一個組合體

     * @param destDir  附件保存目錄

     * @throws UnsupportedEncodingException

     * @throws MessagingException

     * @throws FileNotFoundException

     * @throws IOException

     */

    public  void saveAttachment(Part part, List<com.platform.system.upload.pojo.Attachment> attachments,String rootPath) throws UnsupportedEncodingException, MessagingException,

            FileNotFoundException, IOException {

        if (part.isMimeType("multipart/*" )) {

            Multipart multipart = (Multipart) part.getContent();    //複雜體郵件

            //複雜體郵件包含多個郵件體

            int partCount = multipart.getCount();

            for (int i = 0; i < partCount; i++) {

                //獲得複雜體郵件中其中一個郵件體

                BodyPart bodyPart = multipart.getBodyPart(i);

                String contentType = bodyPart.getContentType();

               

                //某一個郵件體也有可能是由多個郵件體組成的複雜體

                String disp = bodyPart.getDisposition();

 

               

                if (disp != null && (disp.equalsIgnoreCase(Part. ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE ))) {

                    InputStream is = bodyPart.getInputStream();  

                    String fileName = bodyPart.getFileName();

                    fileName = decodeText(fileName);

                    String savefileName = genFileName(fileName);

                    String filePath = getAttachmentPath(fileName);

                    String path = rootPath+getAttachmentPath(fileName);

                   

                    saveFile(is, path,savefileName);

                    com.platform.system.upload.pojo.Attachment attachment = new com.platform.system.upload.pojo.Attachment();

                    attachment.setPath(filePath+ "\\"+savefileName);

                    attachment.setFileName(fileName);

                    attachments.add(attachment);

                } else if (bodyPart.isMimeType("multipart/*")) {

                    saveAttachment(bodyPart,attachments,rootPath);

                } else {                   

                    if (contentType.indexOf("name" ) != -1 || contentType.indexOf("application" ) != -1) {

                        String fileName = decodeText(bodyPart.getFileName());

                        String savefileName = genFileName(fileName);

                        String path = rootPath+getAttachmentPath(fileName)+"\\" +savefileName;

                     

                     saveFile(bodyPart.getInputStream(), path,savefileName);

                        com.platform.system.upload.pojo.Attachment attachment = new com.platform.system.upload.pojo.Attachment();

                        attachment.setPath(path);

                        attachment.setFileName(fileName);

                        attachments.add(attachment);

                    }

                }

            }

        } else if (part.isMimeType("message/rfc822")) {

              saveAttachment((Part) part.getContent(),attachments,rootPath);

        }

    }

    /**

     *

     * @Description:得到保存附件的地址  

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:19:26      

     * @throws

     */

    public  String getAttachmentPath(String fileName){

              Date nowTime = new Date();

                     String year = StringUtil. DateToString(nowTime,"yyyy");

                     String year_month=StringUtil. DateToString(nowTime, "yyyy-MM");

                     String year_month_day=StringUtil. DateToString(nowTime, "yyyy-MM-dd");

               String autoCreatedDateDir = "\\"+year+"\\" +year_month+"\\" +year_month_day;     

              String mailDir = "mail"+autoCreatedDateDir;     

                     

                     String mailPath = mailDir;

               return mailPath;

    }

    /**

     *

     * @Description:得到附件的唯一名稱  

     * @param   

     * @return String 

     * @author 姚金權

     * @since 2015- 4-21 下午3:19:50      

     * @throws

     */

    public  String genFileName(String oldFileName){

       String fileSaveName = StringUtils. join(new String[] { java.util.UUID.randomUUID().toString(), ".",FilenameUtils.getExtension(oldFileName)});

       return fileSaveName;

    }

    

    /**

     * 讀取輸入流中的數據保存至指定目錄

     * @param is 輸入流

     * @param fileName 文件名

     * @param destDir 文件存儲目錄

     * @throws FileNotFoundException

     * @throws IOException

     */

    private  void saveFile(InputStream is, String path,String saveFileName)

            throws FileNotFoundException, IOException {

       File saveFile = new File(path);

       if (!saveFile.exists()){

              saveFile.mkdirs();

              }

       

        BufferedInputStream bis = new BufferedInputStream(is);

        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path+"\\" +saveFileName));

        int len = -1;

        while ((len = bis.read()) != -1) {

            bos.write(len);

            bos.flush();

        }

        bos.close();

        bis.close();

    }

    

    /**

     * 文本解碼

     * @param encodeText 解碼MimeUtility.encodeText(String text)方法編碼後的文本

     * @return 解碼後的文本

     * @throws UnsupportedEncodingException

     */

    public  String decodeText(String encodeText) throws UnsupportedEncodingException {

        if (encodeText == null || "".equals(encodeText)) {

            return "" ;

        } else {

            return MimeUtility.decodeText(encodeText);

        }

    }

 

 

實現了POP3協議允許電子郵件客戶端下載服務器上的郵件,但是在客戶端的操作(如移動郵件、標記已讀等),不會反饋到服務器上,比如通過客戶端收取了郵箱中的3封郵件並移動到其他文件夾,郵箱服務器上的這些郵件是沒有同時被移動的 。而IMAP提供webmail 與電子郵件客戶端之間的雙向通信,客戶端的操作都會反饋到服務器上,對郵件進行的操作,服務器上的郵件也會做相應的動作。

 

爲了讓系統適應新老郵件服務器(兩種不同的協議 pop3和imap) 在EmailSelecter 下實現兩個具體組件

 

a.IMAPEmailSelecter

b.POP3EmailSelecter

 

 

package com.platform.util.mail;

 

import java.util.Properties;

 

import javax.mail.Folder;

import javax.mail.MessagingException;

import javax.mail.URLName;

import javax.mail.internet.MimeMessage;

import com.sun.mail.imap.IMAPFolder;

/**

 *

 * ========================================================

*  上海建業信息科技有限公司  研發中心

*  日  期:2015 -4- 21 下午3:21:45

*  作  者:姚金權

*  版  本:1.0

*  功能描述:基於 imap協議的郵件查詢器

*

*  修訂日期                  修訂人              描述

*  2015-4 -21      姚金權           創建

* ========================================================

 */

public class IMAPEmailSelecter extends EmailSelecter{

       

        String port;

        String host;

        String username;

        String password;

        String protocol;

        public IMAPEmailSelecter(String host,String port,String protocol,String username,String password){

               this.port = port;

               this.host = host;

               this.protocol = protocol;

               this.username = username;

               this.password = password;

       }

        /**

        *    

        * @Description: 初始化配置信息

        * @param   

        * @return URLName 

        * @author 姚金權

        * @since 2015- 4-17 下午6:13:36   

        * @throws

        */

   public  void initProperties(Properties props) throws Exception{

 

              String pop3Port = "110";

               if(port != null){

                     pop3Port = port;

              }             

              

              props.setProperty( "mail.store.protocol", "imap" );       // 協議

               props.setProperty( "mail.imap.host", host );    // pop3服務器

               props.setProperty( "mail.imap.port", "143" );

        }

     /**

        *    

        * @Description: 初始化請求鏈接

        * @param   

        * @return URLName 

        * @author 姚金權

        * @since 2015- 4-17 下午6:13:36   

        * @throws

        */

        @Override

        public URLName initURL() {

               return new URLName(protocol, host, Integer.parseInt(port ), null, username, password );

       }

 

        /**

        *    

        * @Description: 得到郵件的唯一標示

        * @param   

        * @return URLName 

        * @author 姚金權

        * @since 2015- 4-17 下午6:13:36   

        * @throws

        */

        @Override

        public String getUID(Folder folder, MimeMessage msg)

                      throws MessagingException {

              IMAPFolder imapFolder = (IMAPFolder)folder;

              String uid = String. valueOf(imapFolder.getUID(msg));

               return uid;

       }

       

       

       

}

 

 

 

 

package com.platform.util.mail;

 

import java.security.Security;

import java.util.Properties;

 

import javax.mail.Folder;

import javax.mail.MessagingException;

import javax.mail.URLName;

import javax.mail.internet.MimeMessage;

 

import com.platform.oa.commange.mail.pojo.EmailHost;

import com.platform.oa.commange.mail.pojo.UserEmailAccount ;

import com.sun.mail.pop3.POP3Folder;

/**

 *

 * ========================================================

*  上海建業信息科技有限公司  研發中心

*  日  期:2015 -4- 21 下午3:30:05

*  作  者:姚金權

*  版  本:1.0

*  功能描述:基於pop3協議的郵件查詢器

*

*  修訂日期                  修訂人              描述

*  2015-4 -21      姚金權           創建

* ========================================================

 */

public class POP3EmailSelecter extends EmailSelecter {

        String port;

        String host;

        String username;

        String password;

        String protocol;

       

        public POP3EmailSelecter(String host,String port,String protocol,String username,String password){

               this.port = port;

               this.host = host;

               this.protocol = protocol;

               this.username = username;

               this.password = password;

       }

       

        /**

     * @throws Exception

     *

     * @Description: 初始化郵件配置信息 

     * @param   

     * @return void 

     * @author 姚金權

     * @since 2015- 4-3 下午1:48:45

     * @throws

     */

    public  void initProperties(Properties props) throws Exception{        

       props.setProperty( "mail.store.protocol", "pop3" );       // 協議

        props.setProperty( "mail.pop3.port", port );             // 端口

        props.setProperty( "mail.pop3.host", host );    // pop3服務器

        props.setProperty( "mail.pop3.disabletop", "true" ); 

        props.setProperty( "mail.mime.address.strict", "false" );

    }

    

 

        @Override

        public String getUID(Folder folder, MimeMessage msg) throws MessagingException {

              POP3Folder pop3Folder = (POP3Folder)folder;

               return pop3Folder.getUID(msg);

       }

 

        @Override

        public URLName initURL() {

               return new URLName(protocol, host, Integer.parseInt(port ), null, username, password );

       }

}

 

 

 

package com.platform.util.mail;

import java.util.List;

import javax.mail.Message;

import com.platform.oa.commange.mail.pojo.NetworkReceiverEmail;

/**
*
* ========================================================
*  上海建業信息科技有限公司  研發中心
*  日  期:2015-4-3 下午1:43:40
*  作  者:姚金權
*  版  本:1.0
*  功能描述:查詢的收件箱結果
*
*  修訂日期                  修訂人              描述
*  2015-4-3      姚金權           創建
* ========================================================
*/
public class InboxSelectResult {
    
     //未讀郵件數
     private Integer unreadCount;
     //已經刪除郵件數
     private Integer deletedCount;
     //新郵件數
     private Integer newCount;
     //郵件總數
     private Integer count;
     //查詢到的郵件
     private List<NetworkReceiverEmail> emails;
     public Integer getUnreadCount() {
          return unreadCount;
     }
     public void setUnreadCount(Integer unreadCount) {
          this.unreadCount = unreadCount;
     }
     public Integer getDeletedCount() {
          return deletedCount;
     }
     public void setDeletedCount(Integer deletedCount) {
          this.deletedCount = deletedCount;
     }
     public Integer getNewCount() {
          return newCount;
     }
     public void setNewCount(Integer newCount) {
          this.newCount = newCount;
     }
     public Integer getCount() {
          return count;
     }
     public void setCount(Integer count) {
          this.count = count;
     }
    
    
    
     public List<NetworkReceiverEmail> getEmails() {
          return emails;
     }
     public void setEmails(List<NetworkReceiverEmail> emails) {
          this.emails = emails;
     }
     public String toString(){
          return "郵件總數:"+this.count+" 新郵件:"+this.newCount+" 未讀郵件:"+this.unreadCount+" 已刪除郵件:"+this.deletedCount;
     }
    
    
    
}

 

如果用戶勾選SLL安全選項

 

package com.platform.util.mail;

 

import java.security.Security;

import java.util.Properties;

 

public class IMAPSLLEmailSelecter extends IMAPEmailSelecter {

       

        public IMAPSLLEmailSelecter(String host, String port, String protocol,

                     String username, String password) {

               super(host, port, protocol, username, password);

               // TODO Auto-generated constructor stub

       }

       

        public  void initProperties(Properties props) throws Exception{

              String imapPort = "993";

               if(port != null){

                     imapPort = port;

              }

               final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory" ;

              Security. addProvider(new com.sun.net.ssl.internal.ssl.Provider());

              props.setProperty( "mail.imap.socketFactory.class" , SSL_FACTORY);

              props.setProperty( "mail.imap.socketFactory.fallback" , "false" );

              props.setProperty( "mail.imap.port", imapPort);

              props.setProperty( "mail.imap.socketFactory.port" , imapPort);         

              }

       

}

 

 

 

package com.platform.util.mail;

import java.security.Security;
import java.util.Properties;

public class POP3SLLEmailSelecter extends POP3EmailSelecter {
    
     public POP3SLLEmailSelecter(String host, String port, String protocol,
               String username, String password) {
          super(host, port, protocol, username, password);
     }
    
    
     /**
     * @throws Exception
     *
     * @Description: 初始化郵件配置信息 
     * @param   
     * @return void 
     * @author 姚金權
     * @since 2015-4-3 下午1:48:45    
     * @throws
     */
    public  void initProperties(Properties props) throws Exception{
          final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
          Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
          props.setProperty("mail.pop3.socketFactory.class", SSL_FACTORY);
          props.setProperty("mail.pop3.socketFactory.fallback", "false");
          props.setProperty("mail.pop3.port", port);
          props.setProperty("mail.pop3.socketFactory.port", port);
    }
}

 

----
spring mvc+tomcat源碼分析視頻(鏈接複製在瀏覽器打開)

https://study.163.com/course/courseMain.htm?share=2&shareId=480000001919582&courseId=1209399899&_trace_c_p_k2_=6d81bc445e9c462ab8d6345e40f6b0bf

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章