日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
淺談JavaEmail的用法

Email

電子郵件早已成為工作生活中不可缺少的部分,每個(gè)工作的人都會(huì)有自己的私人郵箱或企業(yè)郵箱,用來(lái)協(xié)助我們處理生活事務(wù)以及實(shí)現(xiàn)工作中的交流。

鹽城ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書(shū)銷(xiāo)售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話(huà)聯(lián)系或者加微信:028-86922220(備注:SSL證書(shū)合作)期待與您的合作!

今天主要通過(guò)簡(jiǎn)單的示例,了解在Java中如何使用API來(lái)完成郵件的接收與發(fā)送。

通過(guò)該篇文章我們可以有如下收獲:

  1. 了解基于Java的電子郵件客戶(hù)端的實(shí)現(xiàn)方式
  2. 了解常見(jiàn)的郵箱如何集成
  3. 認(rèn)識(shí)郵箱中的IMAP與POP協(xié)議

適用場(chǎng)景

郵件和短信很像,將信息發(fā)送到目的用戶(hù),不需要用戶(hù)在線,基于郵件服務(wù)器,完成消息的存儲(chǔ)與轉(zhuǎn)發(fā)。一般公司都會(huì)有自己的企業(yè)郵箱,主要也是為了保證數(shù)據(jù)的安全性??赡苣闫綍r(shí)在注冊(cè)網(wǎng)站時(shí),需要通過(guò)郵件來(lái)接收驗(yàn)證消息完成認(rèn)證流程;或者每天打開(kāi)郵箱收到的各種訂閱消息等等。

  1. 基于電子郵件的通信與交流
  2. 接收驗(yàn)證消息,實(shí)現(xiàn)用戶(hù)認(rèn)證
  3. 發(fā)送郵件提供消息通知

說(shuō)明

電子郵件在Internet上發(fā)送和接收的原理與我們通過(guò)郵局發(fā)信件非常相類(lèi)似:首先要找到任何一個(gè)郵局,填寫(xiě)郵件收件人姓名、地址等信息, 之后信件就會(huì)寄到收件人所在地的郵局,對(duì)方需要到相應(yīng)的郵局才能取出信件。同樣,在發(fā)送電子郵件時(shí),郵件是由郵件發(fā)送服務(wù)器發(fā)出, 根據(jù)收信人的地址匹配目的郵件接收服務(wù)器,收信人收取郵件需要訪問(wèn)這個(gè)服務(wù)器才能取件。

郵件的發(fā)送與接收都需要基于特定的通信協(xié)議,發(fā)郵件時(shí)基于SMTP協(xié)議,收郵件時(shí)基于POP3、IMAP協(xié)議。

  • SMTPSMTP 的全稱(chēng)是“Simple Mail Transfer Protocol”,即簡(jiǎn)單郵件傳輸協(xié)議,是用于發(fā)送電子郵件的協(xié)議。它是一組用于從源地址到目的地址傳輸郵件的規(guī)范,通過(guò)它來(lái)控制郵件的中轉(zhuǎn)方式。SMTP 協(xié)議屬于 TCP/IP 協(xié)議簇,它幫助每臺(tái)計(jì)算機(jī)在發(fā)送或中轉(zhuǎn)信件時(shí)找到下一個(gè)目的地。SMTP 服務(wù)器就是遵循 SMTP 協(xié)議的發(fā)送郵件服務(wù)器。
  • IMAPIMAP(Internet Message Access Protocol)Internet郵件訪問(wèn)協(xié)議,是用于接收電子郵件的協(xié)議。IMAP不用對(duì)服務(wù)器上面的郵件進(jìn)行全部下載(根據(jù)實(shí)際需要進(jìn)行下載),可以通過(guò)郵件客戶(hù)端對(duì)郵件進(jìn)行操作;IMAP提供了WebMail與郵件客戶(hù)端之間的雙向通信,以及客戶(hù)端上的操作(如閱讀、刪除、移動(dòng)郵件等)。
  • POP3POP3(Post Office Protocol version 3)郵局協(xié)議的第3個(gè)版本,同樣用于接收電子郵件的協(xié)議。POP3可以讓你下載郵件服務(wù)器上的郵件(下載所有未讀郵件),在郵件從服務(wù)器發(fā)送到電腦的同時(shí)刪除郵件服務(wù)器上的郵件(目前很多郵件服務(wù)器都支持“下載郵件,不刪除郵件,或者發(fā)出提醒”)。

POP允許電子郵件客戶(hù)端下載服務(wù)器上的郵件,但是您在電子郵件客戶(hù)端的操作(如:移動(dòng)郵件、標(biāo)記已讀等),這是不會(huì)反饋到服務(wù)器上的, 比如:您通過(guò)電子郵件客戶(hù)端收取了QQ郵箱中的3封郵件并移動(dòng)到了其他文件夾,這些移動(dòng)動(dòng)作是不會(huì)反饋到服務(wù)器上的,也就是說(shuō),QQ郵箱服務(wù)器上的這些郵件是沒(méi)有同時(shí)被移動(dòng)的。但是IMAP就不同了,電子郵件客戶(hù)端的操作都會(huì)反饋到服務(wù)器上,您對(duì)郵件進(jìn)行的操作(如:移動(dòng)郵件、標(biāo)記已讀等),服務(wù)器上的郵件也會(huì)做相應(yīng)的動(dòng)作。也就是說(shuō),IMAP是“雙向”的。同時(shí),IMAP可以只下載郵件的主題,只有當(dāng)您真正需要的時(shí)候,才會(huì)下載郵件的所有內(nèi)容。

如果感興趣可以深入了解這幾個(gè)協(xié)議的具體實(shí)現(xiàn)與規(guī)范,這里我們只用知道,與郵箱服務(wù)器對(duì)接時(shí),是基于這幾個(gè)協(xié)議來(lái)實(shí)現(xiàn)通信,什么時(shí)候用什么協(xié)議即可。后面示例中會(huì)有用到。

郵箱與協(xié)議

如果要完成郵件的發(fā)送,我們需要知道用戶(hù)通過(guò)服務(wù)器將郵件發(fā)送給誰(shuí),這里的用戶(hù)指的是發(fā)件方,需要明確我們的發(fā)件地址, 誰(shuí)即對(duì)方的郵箱地址,郵箱地址主要郵3個(gè)部分組成,用戶(hù)名@郵件服務(wù)器域名,比如123456@qq.com,tom@gmail.com等等, 上面說(shuō)到的服務(wù)器與域名對(duì)應(yīng)。

在編寫(xiě)示例前,需要先了解我們用到郵箱的一些信息,比如實(shí)現(xiàn)基于qq郵箱的郵件發(fā)送以及收取時(shí),我們必須知道其郵箱服務(wù)器對(duì)應(yīng)的協(xié)議服務(wù)地址以及端口, 下面是幾個(gè)常見(jiàn)的協(xié)議信息:

  • 126郵箱

協(xié)議類(lèi)型

協(xié)議功能

服務(wù)器地址

非SSL端口

SSL端口號(hào)

SMTP

發(fā)送郵件

smtp.126.com

25

465、994

POP

接收郵件

pop.126.com

110

995

IMAP

接收郵件

imap.126.com

143

993

  • 163郵箱

協(xié)議類(lèi)型

協(xié)議功能

服務(wù)器地址

非SSL端口

SSL端口號(hào)

SMTP

發(fā)送郵件

smtp.163.com

25

465

POP

接收郵件

pop.163.com

110

995

IMAP

接收郵件

imap.163.com

143

993

  • QQ郵箱

協(xié)議類(lèi)型

協(xié)議功能

服務(wù)器地址

非SSL端口

SSL端口號(hào)

SMTP

發(fā)送郵件

smtp.qq.com

25

465、587

POP

接收郵件

pop.qq.com

110

995

IMAP

接收郵件

imap.qq.com

143

993

  • Gmail郵箱

協(xié)議類(lèi)型

協(xié)議功能

服務(wù)器地址

非SSL端口

SSL端口號(hào)

SMTP

發(fā)送郵件

smtp.gmail.com

465、587

POP

接收郵件

pop.gmail.com

995

IMAP

接收郵件

imap.gmail.com

993

實(shí)例

在Java中我們可以基于JavaMail API實(shí)現(xiàn)郵件的發(fā)送與讀取,由于我使用的是JDK17,所以選用的是jakarta.mail.jar完成今天的示例。

在Spring中同樣提供了郵件的支持,我們可以在項(xiàng)目中通過(guò)引入spring-boot-starter-mail來(lái)集成,下面分別來(lái)看下如何實(shí)現(xiàn)郵件的收發(fā)功能。示例以QQ郵件為例,比如我的郵箱地址為409835152@qq.com,下面來(lái)看看具體實(shí)現(xiàn)過(guò)程

  • 發(fā)送郵件
  1. 引入依賴(lài)

      org.springframework.boot
      spring-boot-starter-mail
      ${spring-boot.version}
  
  1. 添加application配置
spring:
  mail:
    host: smtp.qq.com
    port: 25
    protocol: smtp
    username: 409835152@qq.com
    password: '******'

這里主要配置了郵箱地址,和上面說(shuō)到的協(xié)議類(lèi)型、服務(wù)地址以及端口,最后還有一個(gè)密碼,注意這里不是郵箱登錄密碼,我們需要單獨(dú)申請(qǐng),這個(gè)在各個(gè)郵箱中都有申請(qǐng)入口,比如qq郵箱中:

圖片

點(diǎn)擊“管理服務(wù)”在新的頁(yè)面中通過(guò)“生成授權(quán)碼”按流程申請(qǐng)即可,注意不要泄露?。?!

圖片

  1. 編寫(xiě)郵件發(fā)送服務(wù)
@Service
public class EmailQQService {

    @Resource
    private JavaMailSender javaMailSender;

    @Resource
    private MailProperties mailProperties;

    public void sendEmail(Email email){
      SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
      simpleMailMessage.setFrom(mailProperties.getUsername()); //設(shè)置發(fā)送郵件賬號(hào)
      simpleMailMessage.setTo(email.getTo()); //設(shè)置接收郵件的人,可以多個(gè)
      simpleMailMessage.setSubject(email.getSubject()); //設(shè)置發(fā)送郵件的主題
      simpleMailMessage.setText(email.getText()); //設(shè)置發(fā)送郵件的內(nèi)容
      javaMailSender.send(simpleMailMessage);
    }
}

主要指定發(fā)送目標(biāo)對(duì)象的郵箱地址,郵件主題以及郵件內(nèi)容等即可??梢钥吹?,基于spring提供的工具,郵件的發(fā)送變得非常簡(jiǎn)單。

  • 郵件的接收

在Spring中沒(méi)有提供這樣的工具類(lèi),需要我們自己寫(xiě):

@Service
public class QqEmailService {
    
    public List receiveEmail() throws MessagingException, IOException {
        Properties properties = configProperties();
        Store store = createStore( properties );
        List emails = receive(store);
        store.close();
        return emails;
    }

}
  1. 添加接收服務(wù)相關(guān)的配置,包括協(xié)議、服務(wù)地址、端口
private Properties configProperties(){
        // 配置郵件服務(wù)器
        Properties properties = new Properties();
        properties.setProperty("mail.store.protocol", receiveMailProperties.getProtocol());
        properties.setProperty("mail.imap.host", receiveMailProperties.getHost());
        properties.setProperty("mail.imap.port", receiveMailProperties.getPort());
        return properties;
    }
  1. 創(chuàng)建Session與Store
private Store createStore(Properties properties) throws MessagingException {
        // 創(chuàng)建Session實(shí)例對(duì)象
        Session session = Session.getInstance( properties );
        // 創(chuàng)建IMAP協(xié)議的Store對(duì)象
        Store store = session.getStore("imap");
        // 連接郵件服務(wù)器
        store.connect(mailProperties.getUsername(), mailProperties.getPassword());
        return store;
    }
  1. 從服務(wù)器讀取郵件
private List receive(Store store) throws MessagingException, IOException {
        // 獲得收件箱
        Folder folder = store.getFolder("INBOX");
        // 以讀寫(xiě)模式打開(kāi)收件箱
        folder.open(Folder.READ_WRITE);
        // 各狀態(tài)郵件數(shù)量
        System.out.println(String.format("收件箱郵件總數(shù):%s,其中,新郵件數(shù):%s,未讀郵件數(shù):%s,",folder.getMessageCount(), folder.getUnreadMessageCount(), folder.getNewMessageCount()));
        // 獲得收件箱的郵件列表
        Message[] messages = folder.getMessages(folder.getMessageCount()-5, folder.getMessageCount());
        System.out.println("------------------------開(kāi)始解析郵件----------------------------------");
        List emailList = new ArrayList<>();
        for (Message message : messages) {
            Email email = new Email()
                    .setFrom(Arrays.stream(message.getFrom()).map(address -> ((InternetAddress)address).getAddress()).collect(Collectors.joining()))
                    .setSubject(message.getSubject())
                    .setContentType(message.getContentType())
                    .setSendDate(message.getSentDate())
                    .setReceiveDate(message.getReceivedDate());


            System.out.println(String.format(">>>>> 郵件來(lái)自:%s,主題:%s,接收時(shí)間:%s", email.getFrom(),
                    email.getSubject(),
                    DateFormatUtils.format(email.getReceiveDate(), DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.getPattern()))
            );
            email.setEmailContents(resolveMessage(message.getContentType(), message));
            System.out.println(String.format("郵件內(nèi)容:%s" , email.getEmailContents()));
            emailList.add(email);
        }
        // 關(guān)閉資源
        folder.close(false);
        return emailList;
    }
  1. 解析郵件內(nèi)容,郵件除了文字,還有圖片,需要根據(jù)消息內(nèi)容類(lèi)型進(jìn)行解析,當(dāng)然發(fā)送消息的時(shí)候,同樣支持各種類(lèi)型的消息,具體可以JavaMailSender的實(shí)現(xiàn)類(lèi)
private List resolveMessage(String contentType, Message message) throws MessagingException, IOException {
        List emailContents = new ArrayList<>();
        resolveMessageContent( message.getContent(), message, emailContent->{
            emailContents.add(emailContent);
        } );
//        return content.toString();
        return emailContents;
    }

    private void resolveMessageContent(Object content, Object parent, Consumer emailContentConsumer) throws MessagingException, IOException {
        if( content instanceof String ){
            emailContentConsumer.accept( new EmailContent(EmailContent.Type.TEXT, (String) content) );
        }else if( content instanceof MimeMultipart){
            MimeMultipart multipart = (MimeMultipart) content;
            int count = multipart.getCount(), index = -1;
            while ( count > ++index ){//  0:純文本;1:html內(nèi)容
                BodyPart bodyPart = multipart.getBodyPart(index);
                Object partContent = bodyPart.getContent();
                resolveMessageContent( partContent, bodyPart, emailContentConsumer);
            }
        }else if( content instanceof BASE64DecoderStream){
            File file = new File(((IMAPBodyPart) parent).getFileName());
            ((BASE64DecoderStream) content).transferTo( new FileOutputStream( file ) );
            emailContentConsumer.accept( new EmailContent(EmailContent.Type.FILE, file.getAbsolutePath()) );
        }else {
            System.out.println(">>>>>>>>>>>>>>>> 郵件內(nèi)容類(lèi)型: "+ content.getClass() );
            emailContentConsumer.accept( new EmailContent(EmailContent.Type.TEXT, content.toString()) );
        }
    }
  1. 關(guān)閉store
store.close();

代碼有點(diǎn)多,但是流程不復(fù)雜且比較清晰。到這里一個(gè)簡(jiǎn)單的針對(duì)qq郵箱的郵件發(fā)送與接收示例就完成了。不管是收郵件還是發(fā)郵件其關(guān)鍵點(diǎn)是:

  1. 郵件收發(fā)對(duì)應(yīng)的協(xié)議類(lèi)型、服務(wù)地址、服務(wù)端口
  2. 發(fā)送郵件用戶(hù)的郵箱地址與授權(quán)碼
  3. 目標(biāo)郵箱地址

剩下的都是些簡(jiǎn)單API調(diào)用的過(guò)程

結(jié)束語(yǔ)

最近學(xué)習(xí)些桌面端應(yīng)用,看到了網(wǎng)易郵箱大師,順便了解了下載Java中如何寫(xiě)一個(gè)客戶(hù)端實(shí)現(xiàn)與各個(gè)郵箱服務(wù)器間完成郵件的讀取與接收。這樣通過(guò)其他語(yǔ)言實(shí)現(xiàn)時(shí)也知道了主要流程與必要的相關(guān)配置信息。


當(dāng)前文章:淺談JavaEmail的用法
本文來(lái)源:http://www.5511xx.com/article/dpsoshs.html