0

我正在使用GNU NNTP连接到localhost 上的作为 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's 以获取指定消息:

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.Message而不是MimeMessage. 诚然,可以实例化一个文件夹 and MimeMessage,但我没有看到从一次运行到另一次运行的任何节省,不能保证getMessageID会返回正确的消息。

我看到的尴尬解决方案可能是创建一个MimeMessage's 的持久文件夹,但这似乎有点矫枉过正。

因此,使用标头,或者Xref然后Message-ID解析和搜索字符串......

有没有更好的办法?

4

1 回答 1

2

javax.mail是一个最小公分母 API,它的行为完全取决于后端是什么。所以,在不知道你在说什么的情况下,真的不可能对你的问题给出一个好的答案。但是,您可能需要直接与您正在交谈的任何人交谈并了解更多有关其行为的信息。

这可能是一个评论而不是一个答案,但我认为这个 API 只是一个薄层的信息可能足以证明这一点。

于 2012-08-12T22:47:24.523 回答