今天同事碰到一个问题,使用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:
indicating at least
JAVA MAIL严格按照RFC 822规范进行操作,没有对分号做处理。大多数邮件服务器都是严格遵循RFC 822规范的,比如Lotus Notes、gmail(gmail的收件人是不能输入分号的,甚至会自动替换成逗号,赞一个);但是,大家也会发现平时发送邮件,经常以分号做分割,这是因为微软的一些邮件工具,如:outlook、outlook Express或是其MAPI,则是以分号为分隔符的,又因为outlook使用用户非常广泛,甚至很多人会认为分号分隔才是规范,强烈鄙视Microsoft!不规范的东西太多了!!
如果足够倒霉,真的碰到了习惯使用分号作为分割符的用户,而其邮件服务器又不会自动将分号替换为逗号,那我们只能通过程序做兼容了,可以考虑修订JAVA MAIL源码,修改
InternetAddress类的parse方法,这里源码就不展现了,大家只需将对于分号的处理修改成和逗号一样即可(但是分号在FRC 822中也有定义,这么修改有可能引起隐患,大家慎重)。