0

GNU NNTPを使用して、ローカルホスト上の NNTP サーバーであるleafnodeに接続しています。GNU API は を使用しますjavax.mail.Messageが、これには次の注意事項があります。

メッセージ APIから:

..特定のメッセージのメッセージ番号は、フォルダ内の他のメッセージが削除および消去された場合、セッション中に変更される可能性があります。

そのため、現在、javax.mail.search既知のメッセージを検索するために使用しています。残念ながら、各検索でフォルダ全体が検索されました。フォルダを開いたままにしておくことで、検索を少し高速化できますが、扱いにくいようです。

を使用する別の方法はjavax.mail.search何ですか? これ:

    SearchTerm st = new MessageIDTerm(id);
    List<Message> messages = Arrays.asList(folder.search(st));

javax.mail.Folderに数個しかない場合は正常に動作しMessageます。ただし、 が非常に大きいFolder場合は、より適切なアプローチが必要です。Message-IDヘッダー フィールドの代わりに、Xref好ましいかもしれませんが、文字列を検索するという同じ基本的な問題があります。

Folder指定されたメッセージの を検索/取得/検索するのに十分な情報を保持する必要があるデータベースは次のとおりです。

mysql> 
mysql> use usenet;show tables;
Database changed
+------------------+
| Tables_in_usenet |
+------------------+
| articles         |
| newsgroups       |
+------------------+
2 rows in set (0.00 sec)

mysql> 
mysql> describe articles;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| ID           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| MESSAGEID    | varchar(255) | YES  |     | NULL    |                |
| NEWSGROUP_ID | bigint(20)   | YES  | MUL | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> 
mysql> describe newsgroups;
+-----------+--------------+------+-----+---------+----------------+
| Field     | Type         | Null | Key | Default | Extra          |
+-----------+--------------+------+-----+---------+----------------+
| ID        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| NEWSGROUP | varchar(255) | YES  |     | NULL    |                |
+-----------+--------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> 

スキーマは現時点では非常に単純ですが、さらに複雑にする予定です。

メッセージは次のように照会されますgetMessage():

package net.bounceme.dur.usenet.model;

import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.*;
import javax.mail.search.MessageIDTerm;
import javax.mail.search.SearchTerm;
import net.bounceme.dur.usenet.controller.Page;

public enum Usenet {

    INSTANCE;
    private final Logger LOG = Logger.getLogger(Usenet.class.getName());
    private Properties props = new Properties();
    private Folder root = null;
    private Store store = null;
    private List<Folder> folders = new ArrayList<>();
    private Folder folder = null;

    Usenet() {
        LOG.fine("controller..");
        props = PropertiesReader.getProps();
        try {
            connect();
        } catch (Exception ex) {
            Logger.getLogger(Usenet.class.getName()).log(Level.SEVERE, "FAILED TO LOAD MESSAGES", ex);
        }
    }

    public void connect() throws Exception {
        LOG.fine("Usenet.connect..");
        Session session = Session.getDefaultInstance(props);
        session.setDebug(true);
        store = session.getStore(new URLName(props.getProperty("nntp.host")));
        store.connect();
        root = store.getDefaultFolder();
        setFolders(Arrays.asList(root.listSubscribed()));
    }

    public List<Message> getMessages(Page page) throws Exception {
        Newsgroup newsgroup = new Newsgroup(page);
        LOG.fine("fetching.." + newsgroup);
        folder = root.getFolder(newsgroup.getNewsgroup());
        folder.open(Folder.READ_ONLY);
        List<Message> messages = Arrays.asList(folder.getMessages());
        LOG.fine("..fetched " + folder);
        return Collections.unmodifiableList(messages);
    }

    public List<Folder> getFolders() {
        LOG.fine("folders " + folders);
        return Collections.unmodifiableList(folders);
    }

    private void setFolders(List<Folder> folders) {
        this.folders = folders;
    }

    public Message getMessage(Newsgroup newsgroup, Article article) throws MessagingException {
        LOG.fine("\n\ntrying.." + newsgroup + article);
        String id = article.getMessageId();
        Message message = null;
        folder = root.getFolder(newsgroup.getNewsgroup());
        folder.open(Folder.READ_ONLY);
        SearchTerm st = new MessageIDTerm(id);
        List<Message> messages = Arrays.asList(folder.search(st));
        LOG.severe(messages.toString());
        if (!messages.isEmpty()) {
            message = messages.get(0);
        }
        LOG.info(message.getSubject());
        return message;
    }
}

私が今気付いている問題は、次のことです。

...the message number for a particular Message can change during a session if other messages in the Folder are deleted and expunged.

どの特定のヘッダーが使用されているかに関係なく、次のようなものです。

Message-ID: <x1-CZwog1NTZLd68+JJY35Zrl9OqXE@gwene.org>

また

Xref: dur.bounceme.net gwene.com.economist:541

そのため、解析と検索が必要な文字列が常に存在するため、これは非常に厄介です。

MimeMessage非常に便利なgetMessageIDメソッドがあることに気付きました。残念ながら、GNU はjavax.mail.Messageand ではなくを使用しMimeMessageます。確かに、フォルダーとをインスタンス化することは可能ですが、ある実行から別の実行に至るまで、正しいメッセージが返さMimeMessageれるという保証はありません。getMessageID

私が見る厄介な解決策は、おそらくの永続的なフォルダーを作成するMimeMessageことですが、それはやり過ぎのようです。

したがって、ヘッダーを使用して、XrefまたはMessage-ID文字列を解析して検索します...

より良い方法はありますか?

4

1 に答える 1

2

javax.mailは最小公分母の API であり、その動作はバックエンドが何であるかに完全に依存します。したがって、あなたが何と話しているのかを知らなければ、あなたの質問に適切な答えを出すことは実際には不可能です. ただし、話している相手に直接話しかけて、その動作について詳しく知る必要がある可能性があります。

これは答えではなくコメントかもしれませんが、この API が単なる薄いレイヤーであるという情報は、正当化するのに十分な情報かもしれないと考えています。

于 2012-08-12T22:47:24.523 に答える