Анализ на основе событий в MIME4J - как заполнить новое сообщение из InputStream?
Я работаю с MIME4J для чтения событий MIME из дампа стека электронной почты. Я пытаюсь прочитать данное событие сообщения, как определено заголовками START_MESSAGE и END_MESSAGE, как целое событие, так как в конечном итоге я буду перемещать процесс в распределенную файловую систему, и мне нужно будет планировать пересечение границ разделением файлов.
Для анализа на основе событий в mime4j необходим интерфейс ContentHandler, и парсер вызывает из него методы, которые требуют, чтобы для него был установлен обработчик. Я экспериментировал с образцом Handler из другого SO-ответа, который расширяет упакованный SimpleContentHandler mime4j, но который действительно только анализирует заголовки.
Я пытаюсь создать свой собственный класс 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, затем с помощью компоновщика скопировать проанализированный поток в него, и я также попытался построить new Message из синтаксического анализа потока, а затем распечатать сообщение, когда читается заголовок END_MESSAGE, но это напечатало нули.
Возможно, я тоже испытываю концептуальную слепую зону. Если это так, я согласен с этим. Спасибо!
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;
}