0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

在Java中如何使用API来完成邮件的接收与发送

科技绿洲 来源:Java技术指北 作者:Java技术指北 2023-09-30 14:09 次阅读

电子邮件早已成为工作生活中不可缺少的部分,每个工作的人都会有自己的私人邮箱或企业邮箱,用来协助我们处理生活事务以及实现工作中的交流。

今天主要通过简单的示例,了解在Java中如何使用API来完成邮件的接收与发送。

通过该篇文章我们可以有如下收获:

  1. 了解基于Java的电子邮件客户端的实现方式
  2. 了解常见的邮箱如何集成
  3. 认识邮箱中的IMAP与POP协议

适用场景

邮件和短信很像,将信息发送到目的用户,不需要用户在线,基于邮件服务器,完成消息的存储与转发。一般公司都会有自己的企业邮箱,主要也是为了保证数据的安全性。可能你平时在注册网站时,需要通过邮件来接收验证消息完成认证流程;或者每天打开邮箱收到的各种订阅消息等等。

  1. 基于电子邮件的通信与交流
  2. 接收验证消息,实现用户认证
  3. 发送邮件提供消息通知

说明

电子邮件在Internet上发送和接收的原理与我们通过邮局发信件非常相类似:首先要找到任何一个邮局,填写邮件收件人姓名、地址等信息, 之后信件就会寄到收件人所在地的邮局,对方需要到相应的邮局才能取出信件。同样,在发送电子邮件时,邮件是由邮件发送服务器发出, 根据收信人的地址匹配目的邮件接收服务器,收信人收取邮件需要访问这个服务器才能取件。

邮件的发送与接收都需要基于特定的通信协议,发邮件时基于SMTP协议,收邮件时基于POP3、IMAP协议。

  • SMTP
    SMTP 的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议,是用于发送电子邮件的协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。
  • IMAP
    IMAP(Internet Message Access Protocol)Internet邮件访问协议,是用于接收电子邮件的协议。IMAP不用对服务器上面的邮件进行全部下载(根据实际需要进行下载),可以通过邮件客户端对邮件进行操作;IMAP提供了WebMail与邮件客户端之间的双向通信,以及客户端上的操作(如阅读、删除、移动邮件等)。
  • POP3
    POP3(Post Office Protocol version 3)邮局协议的第3个版本,同样用于接收电子邮件的协议。POP3可以让你下载邮件服务器上的邮件(下载所有未读邮件),在邮件从服务器发送到电脑的同时删除邮件服务器上的邮件(目前很多邮件服务器都支持“下载邮件,不删除邮件,或者发出提醒”)。

POP允许电子邮件客户端下载服务器上的邮件,但是您在电子邮件客户端的操作(如:移动邮件、标记已读等),这是不会反馈到服务器上的, 比如:您通过电子邮件客户端收取了QQ邮箱中的3封邮件并移动到了其他文件夹,这些移动动作是不会反馈到服务器上的,也就是说,QQ邮箱服务器上的这些邮件是没有同时被移动的。但是IMAP就不同了,电子邮件客户端的操作都会反馈到服务器上,您对邮件进行的操作(如:移动邮件、标记已读等),服务器上的邮件也会做相应的动作。也就是说,IMAP是“双向”的。同时,IMAP可以只下载邮件的主题,只有当您真正需要的时候,才会下载邮件的所有内容。

如果感兴趣可以深入了解这几个协议的具体实现与规范,这里我们只用知道,与邮箱服务器对接时,是基于这几个协议来实现通信,什么时候用什么协议即可。后面示例中会有用到。

邮箱与协议

如果要完成邮件的发送,我们需要知道用户通过服务器将邮件发送给 ,这里的用户指的是发件方,需要明确我们的发件地址, 谁即对方的邮箱地址,邮箱地址主要邮3个部分组成, 用户名 @ 邮件服务器域名 ,比如123456@qq.com,tom@gmail.com等等, 上面说到的服务器与域名对应。

在编写示例前,需要先了解我们用到邮箱的一些信息,比如实现基于qq邮箱的邮件发送以及收取时,我们必须知道其邮箱服务器对应的协议服务地址以及端口, 下面是几个常见的协议信息:

  • 126邮箱
协议类型协议功能服务器地址非SSL端口SSL端口号
SMTP发送邮件smtp.126.com25465、994
POP接收邮件pop.126.com110995
IMAP接收邮件imap.126.com143993
  • 163邮箱
协议类型协议功能服务器地址非SSL端口SSL端口号
SMTP发送邮件smtp.163.com25465
POP接收邮件pop.163.com110995
IMAP接收邮件imap.163.com143993
  • QQ邮箱
协议类型协议功能服务器地址非SSL端口SSL端口号
SMTP发送邮件smtp.qq.com25465、587
POP接收邮件pop.qq.com110995
IMAP接收邮件imap.qq.com143993
  • Gmail邮箱
协议类型协议功能服务器地址非SSL端口SSL端口号
SMTP发送邮件smtp.gmail.com465、587
POP接收邮件pop.gmail.com995
IMAP接收邮件imap.gmail.com993

实例

在Java中我们可以基于JavaMail API实现邮件的发送与读取,由于我使用的是JDK17,所以选用的是jakarta.mail.jar完成今天的示例。

在Spring中同样提供了邮件的支持,我们可以在项目中通过引入spring-boot-starter-mail来集成,下面分别来看下如何实现邮件的收发功能。示例以QQ邮件为例,比如我的邮箱地址为409835152@qq.com,下面来看看具体实现过程

  • 发送邮件
  1. 引入依赖
< dependency >
      < groupId >org.springframework.boot< /groupId >
      < artifactId >spring-boot-starter-mail< /artifactId >
      < version >${spring-boot.version}< /version >
  < /dependency >
  1. 添加application配置
spring:
  mail:
    host: smtp.qq.com
    port: 25
    protocol: smtp
    username: 409835152@qq.com
    password: '******'

这里主要配置了邮箱地址,和上面说到的协议类型、服务地址以及端口,最后还有一个密码,注意这里不是邮箱登录密码,我们需要单独申请,这个在各个邮箱中都有申请入口,比如qq邮箱中:

图片

点击“管理服务”在新的页面中通过“生成授权码”按流程申请即可,注意不要泄露!!!

图片

  1. 编写邮件发送服务
@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()); //设置发送邮件账号
      simpleMailMessage.setTo(email.getTo()); //设置接收邮件的人,可以多个
      simpleMailMessage.setSubject(email.getSubject()); //设置发送邮件的主题
      simpleMailMessage.setText(email.getText()); //设置发送邮件的内容
      javaMailSender.send(simpleMailMessage);
    }
}

主要指定发送目标对象的邮箱地址,邮件主题以及邮件内容等即可。可以看到,基于spring提供的工具,邮件的发送变得非常简单。

  • 邮件的接收

在Spring中没有提供这样的工具类,需要我们自己写:

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

}
  1. 添加接收服务相关的配置,包括协议、服务地址、端口
private Properties configProperties(){
        // 配置邮件服务器
        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. 创建Session与Store
private Store createStore(Properties properties) throws MessagingException {
        // 创建Session实例对象
        Session session = Session.getInstance( properties );
        // 创建IMAP协议的Store对象
        Store store = session.getStore("imap");
        // 连接邮件服务器
        store.connect(mailProperties.getUsername(), mailProperties.getPassword());
        return store;
    }
  1. 从服务器读取邮件
private List< Email > receive(Store store) throws MessagingException, IOException {
        // 获得收件箱
        Folder folder = store.getFolder("INBOX");
        // 以读写模式打开收件箱
        folder.open(Folder.READ_WRITE);
        // 各状态邮件数量
        System.out.println(String.format("收件箱邮件总数:%s,其中,新邮件数:%s,未读邮件数:%s,",folder.getMessageCount(), folder.getUnreadMessageCount(), folder.getNewMessageCount()));
        // 获得收件箱的邮件列表
        Message[] messages = folder.getMessages(folder.getMessageCount()-5, folder.getMessageCount());
        System.out.println("------------------------开始解析邮件----------------------------------");
        List< Email > 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(" >> >> > 邮件来自:%s,主题:%s,接收时间:%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("邮件内容:%s" , email.getEmailContents()));
            emailList.add(email);
        }
        // 关闭资源
        folder.close(false);
        return emailList;
    }
  1. 解析邮件内容,邮件除了文字,还有图片,需要根据消息内容类型进行解析,当然发送消息的时候,同样支持各种类型的消息,具体可以JavaMailSender的实现类
private List< EmailContent > resolveMessage(String contentType, Message message) throws MessagingException, IOException {
        List< EmailContent > emailContents = new ArrayList<  >();
        resolveMessageContent( message.getContent(), message, emailContent- >{
            emailContents.add(emailContent);
        } );
//        return content.toString();
        return emailContents;
    }

    private void resolveMessageContent(Object content, Object parent, Consumer< EmailContent > 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内容
                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(" >> >> >> >> >> >> >> >> 邮件内容类型: "+ content.getClass() );
            emailContentConsumer.accept( new EmailContent(EmailContent.Type.TEXT, content.toString()) );
        }
    }
  1. 关闭store
store.close();

代码有点多,但是流程不复杂且比较清晰。到这里一个简单的针对qq邮箱的邮件发送与接收示例就完成了。不管是收邮件还是发邮件其关键点是:

  1. 邮件收发对应的协议类型、服务地址、服务端口
  2. 发送邮件用户的邮箱地址与授权码
  3. 目标邮箱地址

剩下的都是些简单API调用的过程

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8988

    浏览量

    85131
  • JAVA
    +关注

    关注

    19

    文章

    2954

    浏览量

    104511
  • API
    API
    +关注

    关注

    2

    文章

    1481

    浏览量

    61776
  • 邮件
    +关注

    关注

    0

    文章

    30

    浏览量

    18793
  • 传输协议
    +关注

    关注

    0

    文章

    78

    浏览量

    11426
收藏 人收藏

    评论

    相关推荐

    邮件发送表单数据

    邮件发送表单数据收录日期 : 2000-08-21  使用PHP 向一个指定的邮箱发送数据是非常简单的一件事情,以至于你可能会想,为什么人们不每天用它呢
    发表于 01-11 09:24

    用SpringMVC发送邮件

    1、SpringMVC实现发送邮件  今天来试着用SpringMVC发送邮件,主要需要依赖以下两个包;  《!--spring发送
    发表于 10-21 14:47

    LPSPI_MasterTransferEDMA 此 api可用于为dma或单独的api发送接收数据吗?

    我正在使用 mimxrt1170 我完成了示例我没有找到单独的 api 用于接收 dma 的数据所以 LPSPI_MasterTransferEDMA 这个 api 可以用于
    发表于 03-15 08:43

    高手总结java常用API(免费下载)

    高手总结java常用API(免费下载)。
    发表于 11-06 11:27 0次下载

    使用Java API技巧分析

    本文介绍了一些关于Java API安全和性能方面的简单易用的技巧,其中包括保证API Key安全和开发Web Service方面框架方面
    发表于 09-27 14:09 3次下载

    如何向您选择的某人发送电子邮件

    您可以通过单击左侧的“发送”选项卡确认您的电子邮件是否已发送。它将显示您发送的所有电子邮件。如
    的头像 发表于 12-13 16:35 4994次阅读
    如何向您选择的某人<b class='flag-5'>发送电子邮件</b>

    如何利用Stream API优化Java代码

    使用Stream API优化代码 Java8的新特性主要是Lambda表达式和流,当流和Lambda表达式结合起来一起使用时,因为流申明式处理数据集合的特点,可以让代码变得简洁易读 放大招,流
    的头像 发表于 07-26 14:30 1272次阅读

    基于SpringBoot实现邮件发送

    本项目通过Springboot发送email邮件,包括普通文本邮件 、HTML内容板式邮件 、包含静态资源邮件以及带附件
    的头像 发表于 02-28 14:58 1202次阅读
    基于SpringBoot实现<b class='flag-5'>邮件</b><b class='flag-5'>发送</b>

    如何用python发送接收邮件

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它控制信件的中转方式。
    的头像 发表于 07-11 09:30 913次阅读
    如何用python<b class='flag-5'>发送</b><b class='flag-5'>接收</b><b class='flag-5'>邮件</b>

    基于Java的接口快速开发框架——magic-api

    magic-api 是一个基于Java的接口快速开发框架,编写接口将通过magic-api提供的UI界面完成,自动映射为HTTP接口,无需定义Controller、Service、Da
    发表于 07-19 11:42 874次阅读
    基于<b class='flag-5'>Java</b>的接口快速开发框架——magic-<b class='flag-5'>api</b>

    怎么用Python构建一个自动发送邮件的脚本

    自动发送邮件能应用于许多场景,比如我想要知道股票策略的股票池是否有实时的更新,这时候如果再拉一遍数据,跑一遍脚本,实在是太浪费时间了。为什么不把这一套流程放到服务器上,然后到点自动运行并发送
    的头像 发表于 10-21 14:47 725次阅读
    怎么用Python构建一个自动<b class='flag-5'>发送</b><b class='flag-5'>邮件</b>的脚本

    怎么用Python构建一个自动发送邮件的脚本

    自动发送邮件能应用于许多场景,比如我想要知道股票策略的股票池是否有实时的更新,这时候如果再拉一遍数据,跑一遍脚本,实在是太浪费时间了。为什么不把这一套流程放到服务器上,然后到点自动
    的头像 发表于 10-31 16:36 514次阅读
    怎么用Python构建一个自动<b class='flag-5'>发送</b><b class='flag-5'>邮件</b>的脚本

    如何用Python批量定制化发送邮件

    一封精美的元旦祝福邮件,但是邮件的内容——比如姓名、祝福语等应该怎样动态渲染呢?答案是jinja2. jinja2 是一个Python 的模板引擎,使用jinja2,我们能够邮件HT
    的头像 发表于 11-01 11:32 2063次阅读

    如何使用Python编写脚本来自动发送邮件

    Python是一种非常流行的编程语言,可以用于多种用途,包括自动化任务。其中一个常见的自动化任务是自动发送邮件本文中,我们将介绍如何使用Python编写脚本来自动发送
    的头像 发表于 12-07 11:36 1294次阅读

    使用API连接SMTP服务器的方法

    现代软件开发,电子邮件功能是许多应用程序的必备组件。无论是用户注册、密码重置、通知发送还是营销活动,电子邮件都是与用户沟通的重要方式。S
    的头像 发表于 10-30 18:13 151次阅读