今日、同僚が JAVA MAIL を使用してメールを受信するときに、受信者がリストで受信者リストがセミコロンで区切られている場合、JAVA MAIL で例外が発生し、正常に解析できないという問題に遭遇しました。見てください。たとえば、非常に単純なデモを書きました。
次のようにコードをコピーします。
@テスト
public void testReceiveMail() {
試す {
文字列ホスト = "pop3.163.com";
プロパティ ポップ = new Properties();
Pops.put("mail.pop3.host", ホスト);
Pops.put("mail.pop.auth", "true");
セッション session = Session.getDefaultInstance(pops, null);
ストアストア = session.getStore("pop3");
//メールサーバーに接続します
store.connect(ホスト, "chb_go", "3870359346");
//受信トレイを受信する
フォルダー受信箱 = store.getDefaultFolder().getFolder("INBOX");
//読み取り専用で十分です
inbox.open(フォルダー.READ_ONLY);
//すべてのメーリングリストを取得します
メッセージ[] msg = inbox.getMessages();
FetchProfile プロファイル = new FetchProfile();
profile.add(FetchProfile.Item.ENVELOPE);
inbox.fetch(メッセージ、プロファイル);
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(インターネットアドレス アドレス:toアドレス){
System.out.println(adress.getAddress());
}
}
//開いているリソースを閉じる
if (受信箱 != null)
inbox.close(true);
if (ストア != null)
ストア.close();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (MessagingException e) {
e.printStackTrace();
} catch (例外 e) {
e.printStackTrace();
}
}
非常に簡単ですが、メールを正常に受信し、受信者リストを正常に表示できますが、内部メール サーバーに接続し、受信者がセミコロンで区切られたメールである場合、受信者は正常に表示されません。
仕様を調べたところ、FRC 822 では、次のように受信者をカンマで区切る必要があると規定されていることがわかりました。セミコロン区切りは標準の区切り文字ではないようです。
次のようにコードをコピーします。
宛先 = "宛先" ":" 1#アドレス ;
/ "再送信先" ":" 1#アドレス
/ "cc" ":" 1#アドレス ;
/ "再送信-cc" ":" 1#アドレス
/ "bcc" ":" #アドレス ブラインドカーボン;
/ "再送信-bcc" ":" #アドレス
# 構文はリストを表し、リスト間の内容はカンマで区切られます。次に例を示します。
次のようにコードをコピーします。
2.7. #ルール: リスト
構成要素「#」は、「*」と同様に次のように定義されます。
<l>#<m>要素
少なくとも <l>、最大 <m> 個の要素を 1 つ以上のカンマ (",") で区切って指定します。これにより、'(要素 *("," 要素;) のような通常の形式のリストが非常に簡単になります。 ))' は、「1#element」として表示できます。この構造が使用される場合は常に、null 要素が許可されますが、存在する要素の数には影響しません。つまり、「(element),,(element)」は許可されます。ただし、要素は 2 つだけとしてカウントされます。したがって、少なくとも 1 つの要素が必要な場合、デフォルト値は 0 と無限大であり、「#(要素)」には任意の数が許可されます。ゼロ; 「1#element」には少なくとも 1 つが必要で、「1#2element」には 1 つまたは 2 つが許可されます。
JAVA MAIL は RFC 822 仕様に従って厳密に動作し、セミコロンを扱いません。 Lotus Notes や Gmail など、ほとんどのメール サーバーは RFC 822 仕様に厳密に従っています (Gmail の受信者はセミコロンを入力できません。また、送信時にも自動的にカンマに置き換えられます)。メールはセミコロンで区切られることがよくあります。これは、Outlook、Outlook Express、またはその MAPI などの一部のメール ツールが区切り文字としてセミコロンを使用するためです。また、Outlook はセミコロン区切りが標準であると思います。私はマイクロソフトを強く軽蔑します!不正が多すぎる! !
運悪く、セミコロンを区切り文字として使用することに慣れているユーザーがいて、そのユーザーのメール サーバーが自動的にセミコロンをカンマに置き換えない場合は、プログラムを通じて互換性を持たせるしかありません。JAVA MAIL の改訂を検討してください。
InternetAddress クラスの parse メソッドのソース コードはここでは示しません。セミコロンの処理をカンマと同じになるように変更するだけです (ただし、セミコロンは FRC 822 にも定義されています)。このような変更は隠れた危険を引き起こす可能性があります。ご注意ください)。