栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

POP3、IMAP4和Exchange收取邮件的JAVA开发详解(一)——工具包的整体结构和业务接口

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

POP3、IMAP4和Exchange收取邮件的JAVA开发详解(一)——工具包的整体结构和业务接口

最近在做一个邮件相关的项目,网上找资料时发现,关于发送邮件的资料倒是很多,收取邮件的就很少了。写下个人开发经验,供别人参考吧。

代码的demo下载,别忘了给我一个star~

也可以当成工具包使用,在pom文件中添加


    
 jitpack.io
 https://jitpack.io
    


    com.github.zeemood
    mail-plus
    1.0.3

1. 开发准备

两个邮箱帐号:一个网易的,一个微软的,个人邮箱即可。例如163,hotmail。网易的邮箱主要是用来测试POP3和IMAP4的,hotmail则是用来测试Exchange的。网易邮箱需要在账户设置开通POP3和IMAP4的功能,开通方法如下:

网易使用IMAP的时候,还需要额外开通一次,不然没办法收件,收取邮件会被阻止,提示NO Select Unsafe Login. Please contact kefu@188.com for help。
开通方法是用http://config.mail.163.com/settings/imap/index.jsp?uid=xxxxxx@163.com

把上面链接的uid替换成自己的网易邮箱即可。

2.邮件收取的基本流程

创建邮箱服务器的连接 >> 列举邮箱的文件夹 >> 匹对需要同步的邮件(根据邮件UID进行匹配)>> 解析邮件

根据这个流程,可以抽取成一个接口类IMailService。在抽取之前我们先来了解一下,拉取邮件需要一些什么参数。

  • 收取邮件需要使用到的依赖
    由于我们需要收取的是POP3、IMAP4和Exchange三种不同协议的邮件,会使用到两种不同的邮箱依赖,java mail和Exchange的java依赖,解析邮件的时候额外还需要使用到apache多个依赖和Emoji表情处理的依赖。主要的依赖如下:


    com.microsoft.ews-java-api
    ews-java-api
    2.0




    org.apache.commons
    commons-email
    1.5




    com.vdurmont
    emoji-java
    4.0.0




   com.sun.mail
   javax.mail
   1.6.2
   compile
 
 


    com.alibaba
    fastjson
    1.2.47

  • 邮箱服务需要的基本参数
    无疑 帐号,密码 是必须的。需要提醒一下的是IMAP、POP3的密码是自己设置的,和登录密码一点关系都没有。当然也有其他邮箱服务商开通IMAP和POP3的时候,直接把你登录密码作为协议密码的,如新浪和21cn的邮箱。而Exchange是一个特例,直接就是使用登录密码,也不需要做什么配置。
    然后是服务器地址端口,这个是IMAP和POP3需要的参数,Exchange有提供自动填入服务器地址和端口的函数。
    我们把它抽取成一个配置类MailConnCfg,代码如下:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class MailConnCfg {

    
    private String email;
    
    private String password;
    
    private String host;
    
    private Integer port;
    
    private boolean ssl;

    
    private ProxyTypeEnum proxyType;
    
    private String proxyHost;
    
    private Integer proxyPort;
    
    private String proxyUsername;
    
    private String proxyPassword;
    
    private String socksProxyHost;
    
    private Integer socksProxyPort;

    public MailConnCfg(String email, String password, String host, Integer port) {
 this.email = email;
 this.password = password;
 this.host = host;
 this.port = port;
    }
}

其中的代理配置类型枚举类代码ProxyTypeEnum如下所示


@Getter
@AllArgsConstructor
public enum ProxyTypeEnum {

    
    SOCKS, HTTP;

}
  • 邮箱服务器连接实体类
    因为同时使用了java-mail和微软的ews的依赖,所以创建出来的网络连接实体类并不是一脉相承的父子类,对两个依赖的网络连接实体类进行一下包装(当然,你有更好的方法也可以使用,我能想到的就是用泛型,还有下面这种,我觉得对我的项目方便一点

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class MailConn {

    private POP3Store pop3Store;
    private IMAPStore imapStore;
    private ExchangeService exchangeService;
}
  • 通用的邮件列表项
    每个装有邮件文件夹打开后,都有邮件(废话),但是三种协议的邮件列表项都不一样。打个比方说,IMAPMessage的uid(邮件唯一标识)是纯数字,只针对那个账户和文件夹唯一。而POP3Message的uid则是字符串,不同的帐号邮件id也是唯一的。Exchange就更不用说了,ews和java-mail的封装肯定不一样。但是他们都能被转换成EML文件。所以我们创建一个通用的邮件列表项,来保证接口类。代码如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MailItem {
    private IMAPMessage imapMessage;
    private POP3Message pop3Message;
    private EmailMessage exchangeMessage;
}
  • 通用邮件解析载体
    解析后的邮件数据可以用一个自定义的类来承载,代码如下

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UniversalMail {

    private String uid;
    private String fromer;
    private String receiver;
    private String bcc;
    private String cc;
    private String folder;
    private Boolean hasRead;
    private Boolean hasAttachment;
    private Date sendDate;
    private String title;
    private String emlPath;
    private String content;
    private String email;
    private List attachments;
}

@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
public class UniversalAttachment {
    private String path;
    private String cid;
    private String name;
    private String contentType;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class UniversalRecipient {
    private String name;
    private String email;
}
  • 邮件服务接口类
    IMailService的代码如下所示:

public interface IMailService {

    
    UniversalMail parseEmail(MailItem mailItem, String localSavePath) throws MailPlusException;

    
    List listAll(MailConn mailConn, List existUids) throws MailPlusException;

    
    MailConn createConn(MailConnCfg mailConnCfg, boolean proxy) throws MailPlusException;
}
  • 自定义的异常
    主要是为了统一 一下抛出的邮件异常类型,方便开发,实际显示的异常信息还是原来的信息
@NoArgsConstructor
public class MailPlusException extends Exception {
    private static final long serialVersionUID = -8014572218613182580L;

    public MailPlusException(String message) {
 super(message);
    }
}

下一篇讲下接口三个实现类。

特别提示:对于上面的@Data之类的注解是使用了Lombok依赖,用来生成getter/setter方法。Builder生成Builder方法,不懂可以找下lombok方面的资料

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号