浅析Java Mail无法解析带分号的收件人列表的问题

 更新时间:2013年08月30日 09:30:34   作者:  
JAVA MAIL严格按照RFC 822规范进行操作,没有对分号做处理。大多数邮件服务器都是严格遵循RFC 822规范的

今天同事碰到一个问题,使用JAVA MAIL收取邮件时,如果收件人是个列表,且收件人列表是以分号进行分割的,则JAVA MAIL就会出现异常,不能正常解析,抽空看了一眼,自己写了个简单demo,很简单,例如:

复制代码 代码如下:

        @Test
        public void testReceiveMail() {

                try {
                        String host = "pop3.163.com";
                        Properties pops = new Properties();
                        pops.put("mail.pop3.host", host);
                        pops.put("mail.pop.auth", "true");
                        Session session = Session.getDefaultInstance(pops, null);
                        Store store = session.getStore("pop3");
                        //连接邮件服务器
                        store.connect(host, "chb_go", "3870359346");
                        //收取收件箱
                        Folder inbox = store.getDefaultFolder().getFolder("INBOX");
                        //只读足够了
                        inbox.open(Folder.READ_ONLY);
                        //得到所有邮件列表
                        Message[] msg = inbox.getMessages();
                        FetchProfile profile = new FetchProfile();
                        profile.add(FetchProfile.Item.ENVELOPE);
                        inbox.fetch(msg, profile);
                        for (int i = 0; i < msg.length; i++) {
                                System.out.println("===============================================");
                                System.out.println("主题:"+msg[i].getSubject());
                                InternetAddress[] toAddress = (InternetAddress[]) msg[i].getRecipients(Message.RecipientType.TO);
                                for(InternetAddress adress:toAddress){
                                        System.out.println(adress.getAddress());
                                }
                        }
                        //关闭打开的资源
                        if (inbox != null)
                                inbox.close(true);
                        if (store != null)
                                store.close();
                } catch (NoSuchProviderException e) {
                        e.printStackTrace();
                } catch (MessagingException e) {
                        e.printStackTrace();
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

很简单,可以正常收取邮件、正常显示收件人列表;但是当连接一个内部邮件服务器,并且收件人是以分号为分隔符的邮件时,确实无法正常显示收件人。

查找了一下规范,发现FRC 822规定:收件人之间是要求以逗号为分割,看来分号分割不是标准的分隔符,如下:

复制代码 代码如下:

destination = "To" ":" 1#address ; Primary
/ "Resent-To" ":" 1#address
 / "cc" ":" 1#address ; Secondary
/ "Resent-cc" ":" 1#address
/ "bcc" ":" #address ; Blind carbon
/ "Resent-bcc" ":" #address

而#语法表示一个列表,列表之间的内容以逗号进行分割,例如:
复制代码 代码如下:

2.7. #RULE: LISTS
A construct "#" is defined, similar to "*", as follows:
<l>#<m>element
indicating at least <l> and at most <m> elements, each separated by one or more commas (","). This makes the usual form of lists very easy; a rule such as '(element *("," element))' can be shown as "1#element". Wherever this construct is used, null elements are allowed, but do not contribute to the count of elements present. That is, "(element),,(element)" is permitted, but counts as only two elements. Therefore, where at least one ele- ment is required, at least one non-null element must be present. Default values are 0 and infinity so that "#(element)" allows any number, including zero; "1#element" requires at least one; and "1#2element" allows one or two.

JAVA MAIL严格按照RFC 822规范进行操作,没有对分号做处理。大多数邮件服务器都是严格遵循RFC 822规范的,比如Lotus Notes、gmail(gmail的收件人是不能输入分号的,甚至会自动替换成逗号,赞一个);但是,大家也会发现平时发送邮件,经常以分号做分割,这是因为微软的一些邮件工具,如:outlook、outlook Express或是其MAPI,则是以分号为分隔符的,又因为outlook使用用户非常广泛,甚至很多人会认为分号分隔才是规范,强烈鄙视Microsoft!不规范的东西太多了!!

如果足够倒霉,真的碰到了习惯使用分号作为分割符的用户,而其邮件服务器又不会自动将分号替换为逗号,那我们只能通过程序做兼容了,可以考虑修订JAVA MAIL源码,修改
InternetAddress类的parse方法,这里源码就不展现了,大家只需将对于分号的处理修改成和逗号一样即可(但是分号在FRC 822中也有定义,这么修改有可能引起隐患,大家慎重)。

相关文章

  • SSM 实现登录验证码功能(附源码)

    SSM 实现登录验证码功能(附源码)

    这篇文章主要介绍了SSM 实现登录验证码功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-12-12
  • java后端访问https证书的问题及解决

    java后端访问https证书的问题及解决

    这篇文章主要介绍了java后端访问https证书的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • JSON在Java中的使用方法实例

    JSON在Java中的使用方法实例

    对于java来说,json的对象也是分为JSONObject和JSONArray这两种,每种对象的操作方式不一样哦,下面这篇文章主要给大家介绍了关于JSON在Java中使用的相关资料,需要的朋友可以参考下
    2023-03-03
  • Java后台Controller实现文件下载操作

    Java后台Controller实现文件下载操作

    这篇文章主要介绍了Java后台Controller实现文件下载操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Java可视化之实现文本的加密和解密

    Java可视化之实现文本的加密和解密

    这篇文章主要介绍了Java可视化之实现文本的加密和解密,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • java后端进行跨域的几种方式小结

    java后端进行跨域的几种方式小结

    本文主要介绍了java后端进行跨域的几种方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • 关于bootstrap.yml和bootstrap.properties的优先级问题

    关于bootstrap.yml和bootstrap.properties的优先级问题

    这篇文章主要介绍了关于bootstrap.yml和bootstrap.properties的优先级问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 微信小程序之搜索分页功能的实现代码

    微信小程序之搜索分页功能的实现代码

    这篇文章主要介绍了微信小程序之搜索分页功能的实现代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • 详解Java实现批量压缩图片裁剪压缩多种尺寸缩略图一键批量上传图片

    详解Java实现批量压缩图片裁剪压缩多种尺寸缩略图一键批量上传图片

    这篇文章主要介绍了Java实现批量压缩图片裁剪压缩多种尺寸缩略图一键批量上传图片,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • JAVA实现FTP断点上传的方法

    JAVA实现FTP断点上传的方法

    这篇文章主要介绍了JAVA实现FTP断点上传的方法,涉及java使用FTP实现文件传输的相关技巧,需要的朋友可以参考下
    2015-06-06

最新评论