使用可能なものは次のとおりです。
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桁)が役に立ちました。 ただし、多くの場合、この時間はメッセージヘッダーの時間と異なる場合があるため、名前の時間はディレクトリ内のメッセージをフィルタリングするためだけに使用しました。
追加/クライアントフラグ
クライアントメールインターフェイス(以下、クライアントと呼びます)は、独自のフラグをレター名に追加できます。 クライアントフラグの開始は、記号「:」で示されます。
クライアント
- 「1」-ドキュメントに「実験的意味を持つフラグ」と書かれています。
- 「2」は、私が実際に100%のケースで持っていたものです。 コンマの後の各後続文字が個別のフラグであることを意味します。
サーバー上のメッセージが既に「読み取り」フォルダーにあるという事実にもかかわらず、ユーザーにはそれが新規として表示されます。 顧客は手紙の場所ではなく、フラグを読みます。
つまり、ユーザー自身が手紙(または彼との別のアクション)を開き、フラグ "S"(表示)が名前に追加された場合にのみ、視覚的に "読み上げられます"。 手紙に対するさまざまなアクションは、予想どおり、フラグを追加し、メモを参照してください。
例:
メールボックスの新しいメッセージがサーバーに届きました。名前は次のようになります。
1348142977.M852516P31269.mail.example.com,S=3309,W=3371
私たちの背景では、
1348142977.M852516P31269.mail.example.com,S=3309,W=3371:2,
次に、
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に制限されています。
モジュールはサーバー上でスピンするため、ローカルでメッセージにアクセスします(コード内のチェックと例外処理は省略されます)。
// properties Session session = Session.getDefaultInstance(System.getProperties()); FileInputStream fis = new FileInputStream(pathToMessage); MimeMessage mimeMessage = new MimeMessage(session, fis);
これで、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ヘッダーのメッセージ本文(およびその部分)に指定されています。
// if(mimeMessage.isMimeType("multipart/mixed")){ // getContent() , . // - Object, Multipart Multipart multipart = (Multipart) mimeMessage.getContent(); // for(int i = 0; i < multipart.getCount(); i ++){ BodyPart part = multipart.getBodyPart(i); // html- , "text/plain" "text/html" ( html ), : if(part.isMimeType("text/plain")){ System.out.println(part.getContent().toString()); } // part else if(Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()){ // . , decode String fileName = MimeUtility.decodeText(part.getFileName()); // InputStream InputStream is = part.getInputStream(); // , - .... } } } // else if(mimeMessage.isMimeType("text/plain")){ System.out.println(mimeMessage.getContent().toString()); }
実際、それがすべてです。 資料が役に立てば幸いです。
また、oracle.comには便利なjavax.mail FAQがあります。
UPD:最初のコメントで述べたように、メッセージの本文部分は一緒にネストできます。 同じ場所のコメントでは、それらを整理するために2つの方法がレイアウトされています。