1

我正在使用 MIME4J 从电子邮件堆栈转储中读取 MIME 事件。我正在尝试将 START_MESSAGE 和 END_MESSAGE 标头定义的给定消息事件作为一个完整事件读取,因为我最终会将进程移动到分布式文件系统,并且需要计划文件拆分边界遍历。

对于 mime4j 中基于事件的解析,需要一个 ContentHandler 接口,解析器从它调用方法,这需要将处理程序设置为它。我已经尝试了来自另一个 SO 答案的示例处理程序,它扩展了 mime4j 打包的 SimpleContentHandler,但实际上只解析标题。

我正在尝试构建我的自定义 ContentHandler 类来收集完整的消息作为一个事件。然后我需要将事件放在一个临时对象中,这样我就可以解析标题、它们的字段以及字段的内容。最终目标是将这种行为适应 MapReduce,因此有必要应对电子邮件的一部分位于一个文件拆分中而另一部分位于不同文件拆分中的可能性。

对于我的自定义 ContentHandler,我已经做到了:

public class CustomContentHandler extends AbstractContentHandler {}

对于一个主要的,我正在使用:

    public class Reader 
    {
     public static void main( String[] args ) throws FileNotFoundException, IOException,
     MimeException
    {

   QaContentHandler handler = new CustomContentHandler();
   MimeConfig config = new MimeConfig();
   MimeStreamParser parser = new MimeStreamParser(config);
   InputStream stream = new FileInputStream("/home/javadev1/lib/INBOX");

   parser.setContentHandler(handler);
   try 
   {
    do 
    {   
   parser.parse(stream);
   }
    while (stream.read() != -1);
       } 
   finally 
    {
           stream.close();
       }
    }

    }

因此,任何有关如何在处理程序中构建信息的帮助都会非常有帮助。我尝试设置一个新的 MessageImpl,然后使用构建器将解析的流复制到其中,我还尝试从流的解析中构建一个 newMessage,然后在读取 END_MESSAGE 标头时打印消息,但是它打印空值。

我可能也遇到了一个概念盲点。如果是这样的话,我可以接受指出。谢谢!

4

1 回答 1

1

这是对我有用的代码摘录。一旦我使用基于状态的解析器发现一条有趣的消息,我就会切换到 dom 解析器来创建一个消息对象。

/**
 * check the MessageStream
 * 
 * @param in - the inputstream to check
 * @param id - the id of a message to search for
 * @param encoding - the encoding of the stream e.g. ISO-8859
 * @return - the message with the given id of null if none is found
 * @throws IOException
 * @throws MimeException
 */
public Message checkMessageStream(InputStream in, String id, Charset encoding)
        throws IOException, MimeException {
    // https://james.apache.org/mime4j/usage.html
    String messageString = new String(StreamUtils.getBytes(in));
    messageString = fixMessageString(messageString);
    InputStream instream = new ByteArrayInputStream(
            messageString.getBytes(encoding));
    MimeTokenStream stream = new MimeTokenStream();
    stream.parse(instream);
    for (EntityState state = stream.getState(); state != EntityState.T_END_OF_STREAM; state = stream
            .next()) {
        switch (state) {
        case T_BODY:
            if (debug) {
                System.out.println("Body detected, contents = "
                        + stream.getInputStream() + ", header data = "
                        + stream.getBodyDescriptor());
            }
            break;
        case T_FIELD:
            Field field = stream.getField();
            if (debug) {
                System.out.println("Header field detected: " + stream.getField());
            }
            if (field.getName().toLowerCase().equals("message-id")) {
                // System.out.println("id: " + field.getBody() + "=" + id + "?");
                if (field.getBody().equals("<" + id + ">")) {
                    InputStream messageStream = new ByteArrayInputStream(
                            messageString.getBytes(encoding));
                    Message message = MessageServiceFactory.newInstance()
                            .newMessageBuilder().parseMessage(messageStream);
                    return message;
                } else {
                    return null;
                }
            }

            break;
        case T_START_MULTIPART:
            if (debug) {
                System.out.println("Multipart message detexted," + " header data = "
                        + stream.getBodyDescriptor());
            }
            break;
        }
    }
    return null;
}
于 2014-07-18T12:02:18.097 回答