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

所属分类: 软件编程 / java 阅读数: 39
收藏 0 赞 0 分享

今天同事碰到一个问题,使用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中也有定义,这么修改有可能引起隐患,大家慎重)。

更多精彩内容其他人还在看

JAVA多线程和并发基础面试问答(翻译)

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题
收藏 0 赞 0 分享

Java List双击事件实现方法

这篇文章主要介绍了Java List双击事件实现方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Java开发者结合Node.js编程入门教程

这篇文章主要介绍了Java开发者结合Node.js编程入门教程,我将先向您展示如何使用Java EE创建一个简单的Rest服务来读取 MongoDB数据库。然后我会用node.js来实现相同的功能,需要的朋友可以参考下
收藏 0 赞 0 分享

Java数组操作的10大方法

下面是精心整理的Java数组操作的10大方法,大部分代码都来自Stack Overflow,需要的朋友可以参考下
收藏 0 赞 0 分享

Java中的StringBuilder性能测试

这篇文章主要介绍了Java中的StringBuilder性能测试,本文包含测试代码和测试结果,最后得出结论,需要的朋友可以参考下
收藏 0 赞 0 分享

Java基于高精度整型实现fibonacci数列的方法

这篇文章主要介绍了Java基于高精度整型实现fibonacci数列的方法,是比较典型的算法,需要的朋友可以参考下
收藏 0 赞 0 分享

Java、JavaScript、Oracle、MySQL中实现的MD5加密算法分享

这篇文章主要介绍了Java、JavaScript、Oracle、MySQL中实现的MD5加密算法分享,需要的朋友可以参考下
收藏 0 赞 0 分享

Java实现的连续奇数(n+2*x)是合数的算法题暴力算法

这篇文章主要介绍了Java实现的连续奇数(n+2*x)是合数的算法题暴力算法,本文包含运算结果和实现代码,需要的朋友可以参考下
收藏 0 赞 0 分享

java异常机制分析

这篇文章主要介绍了java异常机制,包括异常机制的捕获、抛出及常见的异常机制总结,需要的朋友可以参考下
收藏 0 赞 0 分享

Java使用JDBC连接数据库的实现方法

这篇文章主要介绍了Java使用JDBC连接数据库的实现方法,包括了详细的加载步骤以及完整实现示例,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多