如何使用javax.mail读取邮件正文中的文本

问题描述 投票:34回答:6

我正在使用javax.mail开发客户端邮件来读取邮箱内的邮件:

Properties properties = System.getProperties();  
properties.setProperty("mail.store.protocol", "imap");  
try {  
    Session session = Session.getDefaultInstance(properties, null);
    Store store = session.getStore("pop3");//create store instance  
    store.connect("pop3.domain.it", "mail.it", "*****");  
    Folder inbox = store.getFolder("inbox");  
    FlagTerm ft = new FlagTerm(new Flags(Flags.Flag.SEEN), false);
    inbox.open(Folder.READ_ONLY);//set access type of Inbox  
    Message messages[] = inbox.search(ft);
    String mail,sub,bodyText="";
    Object body;
    for(Message message:messages) {
        mail = message.getFrom()[0].toString();
        sub = message.getSubject();
        body = message.getContent();
        //bodyText = body.....
    }
} catch (Exception e) {  
    System.out.println(e);    
}

我知道方法getContent()返回一个对象导致内容可能是StringMimeMultiPartSharedByteArrayInputstream和其他(我认为)...有没有办法让消息体内的文本始终?谢谢!!

java mime multipart javax.mail
6个回答
57
投票

这个答案扩展了yurin's answer。他提出的问题是,MimeMultipart的内容本身可能是另一个MimeMultipart。下面的getTextFromMimeMultipart()方法在这种情况下对内容进行了处理,直到消息体被完全解析为止。

private String getTextFromMessage(Message message) throws MessagingException, IOException {
    String result = "";
    if (message.isMimeType("text/plain")) {
        result = message.getContent().toString();
    } else if (message.isMimeType("multipart/*")) {
        MimeMultipart mimeMultipart = (MimeMultipart) message.getContent();
        result = getTextFromMimeMultipart(mimeMultipart);
    }
    return result;
}

private String getTextFromMimeMultipart(
        MimeMultipart mimeMultipart)  throws MessagingException, IOException{
    String result = "";
    int count = mimeMultipart.getCount();
    for (int i = 0; i < count; i++) {
        BodyPart bodyPart = mimeMultipart.getBodyPart(i);
        if (bodyPart.isMimeType("text/plain")) {
            result = result + "\n" + bodyPart.getContent();
            break; // without break same text appears twice in my tests
        } else if (bodyPart.isMimeType("text/html")) {
            String html = (String) bodyPart.getContent();
            result = result + "\n" + org.jsoup.Jsoup.parse(html).text();
        } else if (bodyPart.getContent() instanceof MimeMultipart){
            result = result + getTextFromMimeMultipart((MimeMultipart)bodyPart.getContent());
        }
    }
    return result;
}

18
投票

这个答案扩展了qazxsw poi以纠正qazxsw poi(Austin's answer)治疗的原始问题。

文本出现两次,因为对于multipart/alternative,用户代理只能选择一个部分。

来自// without break same text appears twice in my tests

“multipart / alternative”类型在语法上与“multipart / mixed”相同,但语义不同。特别地,每个身体部位是相同信息的“替代”版本。

系统应该认识到各个部分的内容是可以互换的。系统应根据本地环境和参考选择“最佳”类型,在某些情况下甚至通过用户交互。与“multipart / mixed”一样,身体部位的顺序也很重要。在这种情况下,替代方案以对原始内容的忠诚度增加的顺序出现。通常,最佳选择是接收方系统本地环境支持的类型的最后部分。

与替代品处理相同的例子:

multipart/alternative

请注意,这是一个非常简单的示例。它错过了很多案例,不应该以当前格式用于生产。


10
投票

下面是在bodyParts是text和html的情况下从消息中获取文本的方法。

RFC2046

更新。有一种情况,bodyPart本身可以是multipart类型。 (在写完这个答案之后我遇到了这样的电子邮件。)在这种情况下,你需要用递归重写上面的方法。


9
投票

我不这么认为,否则如果private String getTextFromMessage(Message message) throws IOException, MessagingException { String result = ""; if (message.isMimeType("text/plain")) { result = message.getContent().toString(); } else if (message.isMimeType("multipart/*")) { MimeMultipart mimeMultipart = (MimeMultipart) message.getContent(); result = getTextFromMimeMultipart(mimeMultipart); } return result; } private String getTextFromMimeMultipart( MimeMultipart mimeMultipart) throws IOException, MessagingException { int count = mimeMultipart.getCount(); if (count == 0) throw new MessagingException("Multipart with no body parts not supported."); boolean multipartAlt = new ContentType(mimeMultipart.getContentType()).match("multipart/alternative"); if (multipartAlt) // alternatives appear in an order of increasing // faithfulness to the original content. Customize as req'd. return getTextFromBodyPart(mimeMultipart.getBodyPart(count - 1)); String result = ""; for (int i = 0; i < count; i++) { BodyPart bodyPart = mimeMultipart.getBodyPart(i); result += getTextFromBodyPart(bodyPart); } return result; } private String getTextFromBodyPart( BodyPart bodyPart) throws IOException, MessagingException { String result = ""; if (bodyPart.isMimeType("text/plain")) { result = (String) bodyPart.getContent(); } else if (bodyPart.isMimeType("text/html")) { String html = (String) bodyPart.getContent(); result = org.jsoup.Jsoup.parse(html).text(); } else if (bodyPart.getContent() instanceof MimeMultipart){ result = getTextFromMimeMultipart((MimeMultipart)bodyPart.getContent()); } return result; } 的mime类型是 import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.internet.MimeMultipart; import org.jsoup.Jsoup; .... private String getTextFromMessage(Message message) throws Exception { if (message.isMimeType("text/plain")){ return message.getContent().toString(); }else if (message.isMimeType("multipart/*")) { String result = ""; MimeMultipart mimeMultipart = (MimeMultipart)message.getContent(); int count = mimeMultipart.getCount(); for (int i = 0; i < count; i ++){ BodyPart bodyPart = mimeMultipart.getBodyPart(i); if (bodyPart.isMimeType("text/plain")){ result = result + "\n" + bodyPart.getContent(); break; //without break same text appears twice in my tests } else if (bodyPart.isMimeType("text/html")){ String html = (String) bodyPart.getContent(); result = result + "\n" + Jsoup.parse(html).text(); } } return result; } return ""; } 会发生什么? API会返回一个Part,因为在内部它会尝试为您提供有用的东西,前提是您知道预期的内容。对于通用软件,它的用途如下:

image/jpeg

你也有原始的(实际上不那么原始,看到Javadoc)Object,但我认为假设你收到的每条消息都是基于文本的消息是不安全的 - 除非你正在编写一个非常具体的应用程序并且你有控制权在输入源上。


4
投票

如果你想总是得到文本,那么你可以跳过其他类型,如'multipart'等...

if (part.isMimeType("text/plain")) {
   ...
} else if (part.isMimeType("multipart/*")) {
   ...
} else if (part.isMimeType("message/rfc822")) {
   ...
} else {
   ...
}

1
投票

不要重新发明轮子!您只需使用Apache Commons Email(请参阅Part.getInputStream()

科特林的例子:

  Object body = message.getContent(); 
    if(body instanceof String){
    // hey it's a text
    }

如果电子邮件没有html内容,但它有简单的内容(你可以通过herefun readHtmlContent(message: MimeMessage) = MimeMessageParser(message).parse().htmlContent 方法检查),那么你应该使用这个代码:

hasPlainContent

Java示例:

hasHtmlContent
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.