Javaで80%を作成した最後のプロジェクトに、サーバーを通過するすべての文字のパーサーであるモジュールを追加する必要がありました。 モジュールの宗教的な動機は非常に奇妙ですが、詳細を共有したいと思います。
使用可能なものは次のとおりです。
CentOS上のDovecot配信サービスを備えたPostfixメールサーバー。 さて、JVM。
メッセージ構造
電子メール、そのコンポーネント、それらのおおよその構造、ヘッダー、MIMEタイプとは、
Wikipediaで人間的に説明されています。
さらに興味深いのは、サーバー上のレターの
ファイル名の構造です。 新しく作成された(クライアントによって要求されていない/読まれていない)手紙の名前の例:
1348142977.M852516P31269.mail.example.com,S=3309,W=3371
名前はフラグで構成されます。 フラグは、新しい文字を作成するとき、文字とそのサイズが示される「場所」、「いつ」、コンマで区切られます。
- 2つの文字サイズが示されています。 「S」およびVsizeで示される通常のサイズは、rfc822.SIZEのシンボル「W」で示されます。 ( ここで彼らは「RFC822.SIZEとは何か?」という質問に答えます)。
- 時間はUnix形式で秒単位で示されます。
- あるフラグでは、時間の経過とともに、ポイントを通過して、名前の一意性のために追加された「P」-プロセスIDおよび「M」-マイクロ秒単位のカウンターに進むことができます(さらにメモに他の属性がある場合があります)
- サーバーは最後のサーバーとして示されます。 手紙が保存されたものであり、手紙が転送された場合のリレーサーバーではありません。
このうち、筆記時間(最初の10桁)が役に立ちました。 ただし、多くの場合、この時間はメッセージヘッダーの時間と異なる場合があるため、名前の時間はディレクトリ内のメッセージをフィルタリングするためだけに使用しました。
追加/クライアントフラグ
クライアントメールインターフェイス(以下、クライアントと呼びます)は、独自のフラグをレター名に追加できます。 クライアントフラグの開始は、記号「:」で示されます。
クライアント
がサーバーから新しいレター
を要求するとすぐに、要求がトランスポートに送信され、要求された各レターが「読み取り」ディレクトリに移動され、次のフラグとカンマで区切られた情報フラグ(2つのうちの1つ)が名前に追加されます:
- 「1」-ドキュメントに「実験的意味を持つフラグ」と書かれています。
- 「2」は、私が実際に100%のケースで持っていたものです。 コンマの後の各後続文字が個別のフラグであることを意味します。
サーバー上のメッセージが既に「読み取り」フォルダーにあるという事実にもかかわらず、ユーザーにはそれが新規として表示されます。 顧客は手紙の場所ではなく、フラグを読みます。
つまり、ユーザー自身が手紙(または彼との別のアクション)を開き、フラグ "S"(表示)が名前に追加された場合にのみ、視覚的に "読み上げられます"。 手紙に対するさまざまなアクションは、予想どおり、フラグを追加し、メモを参照してください。
例:メールボックスの新しいメッセージがサーバーに届きました。名前は次のようになります。
1348142977.M852516P31269.mail.example.com,S=3309,W=3371
私たちの背景では、
神は Outlookを
禁止しています。Outlookは新しい文字のリストを要求し、サーバー上でそれらを「読み取り」ディレクトリに移動してフラグを追加するように言っています。
1348142977.M852516P31269.mail.example.com,S=3309,W=3371:2,
次に、
削除してOutlookを開き、新しい文字をクリックすると、Sフラグが追加されます。
1348142977.M852516P31269.mail.example.com,S=3309,W=3371:2,S
そして、それに答えて削除します:
1348142977.M852516P31269.mail.example.com,S=3309,W=3371:2,SRT
ご覧のとおり、フラグはセパレータなしでリストされています。
注:一部のクライアントには、レターを「読み取り」フォルダーに構成する(移動しない)機能があります。 また、クライアントは、ドキュメントに示されていない「ニーズに応じて」フラグを追加することがありますが、特に注意していません。
より有用なフラグ情報:
cr.yp.to/proto/maildir.htmlそして少しのJava
文字の処理には、
javax.mailを使用しました。 抽象クラス
javax.mail.Messageが提供されていますが、この場合は
javax.mail.MimeMessageに制限されています。
モジュールはサーバー上でスピンするため、ローカルでメッセージにアクセスします(コード内のチェックと例外処理は省略されます)。
これで、ASCIIで予期されるメッセージヘッダーを読み取ることができます。 ヘッダーが見つからない場合、nullを返します。 例:
String messageSubject = mimeMessage.getSubject(); String messageId = mimeMessage.getMessageID();
受信者のリストを決定するために、引数としてMessage.RecipientTypeを取るgetRecipientsメソッドが提供されます。 このメソッドは、
Address型のオブジェクトの配列を返します。 たとえば、メッセージの受信者をリストします。
for(Address recipient : mimeMessage.getRecipients(Message.RecipientType.TO)){ System.out.println(recipient.toString()); }
手紙の差出人を見つけるために、getFromメソッドがあります。 また、Address型のオブジェクトの配列を返します。 このメソッドは、「From」ヘッダーを読み取り、存在しない場合は「Sender」ヘッダーを読み取り、「Sender」が存在しない場合はnullを読み取ります。
for(Address sender : mimeMessage.getFrom()){ System.out.println(sender.toString()); }
次に、メッセージの本文を分析します(ほとんどの場合、テキストと添付ファイルが必要です)。 複合(MIMEマルチパートメッセージ)にすることも、1ブロックのテキスト/プレーン形式のみを含めることもできます。 メッセージの本文が添付ファイル(テキストなし)のみで構成されている場合でも、マルチパートメッセージとしてマークされます。 RFC822によると、フォーマットはContent-Typeヘッダーのメッセージ本文(およびその部分)に指定されています。
実際、それがすべてです。 資料が役に立てば幸いです。
また、oracle.comには便利なjavax.mail
FAQがあります。
UPD:最初のコメントで述べたように、メッセージの本文部分は一緒にネストできます。 同じ場所のコメントでは、それらを整理するために2つの方法がレイアウトされています。