You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从JavaMail API的msg.getContent()中提取纯文本而非HTML代码?

提取JavaMail邮件纯文本的解决方案

核心思路

优先读取邮件原生的text/plain格式内容,这是邮件发送方提供的纯文本版本,最准确;如果邮件只有text/html格式,则将HTML代码转换为纯文本。

方法一:优先获取原生纯文本(推荐)

修改你处理BodyPart的逻辑,通过判断内容类型来提取对应格式的内容:

修改后的ReceiveMail类关键代码

class ReceiveMail extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        Session session = this.getImapSession();
        String messageContent = "";
        try {
            Store store = session.getStore("imaps");
            store.connect("imap.gmail.com", 993, username, password);
            IMAPFolder inbox = (IMAPFolder) store.getFolder("INBOX");
            inbox.open(Folder.READ_WRITE);
            Message[] messages = inbox.getMessages();
            
            for (Message msg : messages) {
                try {
                    fromAddress = msg.getFrom();
                    from = fromAddress[0].toString();
                    subject = msg.getSubject();
                    toList = msg.getRecipients(Message.RecipientType.TO);
                    ccList = msg.getRecipients(Message.RecipientType.CC);
                    
                    Object msgContent = msg.getContent();
                    // 用于存储最终提取的纯文本
                    StringBuilder plainText = new StringBuilder();

                    if (msgContent instanceof Multipart) {
                        Multipart multipart = (Multipart) msgContent;
                        // 递归处理Multipart(处理嵌套情况)
                        extractPlainTextFromMultipart(multipart, plainText);
                    } else {
                        // 非Multipart邮件,直接处理内容
                        String contentType = msg.getContentType();
                        if (contentType.toLowerCase().contains("text/plain")) {
                            plainText.append(msg.getContent().toString());
                        } else if (contentType.toLowerCase().contains("text/html")) {
                            // 转换HTML为纯文本
                            plainText.append(htmlToPlainText(msg.getContent().toString()));
                        } else {
                            // 其他类型,直接转字符串(可能不是文本)
                            plainText.append(msg.getContent().toString());
                        }
                    }
                    content = plainText.toString();
                    System.out.println("提取的纯文本内容:" + content);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return messageContent;
    }

    // 递归处理Multipart,提取纯文本
    private void extractPlainTextFromMultipart(Multipart multipart, StringBuilder plainText) throws Exception {
        for (int k = 0; k < multipart.getCount(); k++) {
            BodyPart bodyPart = multipart.getBodyPart(k);
            String disposition = bodyPart.getDisposition();

            if (disposition != null && disposition.equalsIgnoreCase("ATTACHMENT")) {
                System.out.println("邮件包含附件:" + bodyPart.getDataHandler().getName());
            } else {
                Object partContent = bodyPart.getContent();
                String contentType = bodyPart.getContentType().toLowerCase();

                if (partContent instanceof Multipart) {
                    // 嵌套Multipart,递归处理
                    extractPlainTextFromMultipart((Multipart) partContent, plainText);
                } else if (contentType.contains("text/plain")) {
                    plainText.append(partContent.toString());
                } else if (contentType.contains("text/html")) {
                    plainText.append(htmlToPlainText(partContent.toString()));
                }
                // 忽略其他非文本类型的内容
            }
        }
    }

    // 正则表达式将HTML转换为纯文本
    private String htmlToPlainText(String html) {
        if (html == null || html.isEmpty()) {
            return "";
        }
        // 1. 移除HTML标签
        String plainText = html.replaceAll("<[^>]+>", "");
        // 2. 替换HTML实体(如&nbsp;、&lt;等)
        plainText = plainText.replaceAll("&nbsp;", " ")
                             .replaceAll("&lt;", "<")
                             .replaceAll("&gt;", ">")
                             .replaceAll("&amp;", "&")
                             .replaceAll("&quot;", "\"")
                             .replaceAll("&apos;", "'");
        // 3. 移除多余换行和空格
        plainText = plainText.replaceAll("\\s+", " ").trim();
        return plainText;
    }
}

方法二:使用第三方库处理HTML(更可靠)

如果正则表达式无法处理复杂HTML(比如嵌套标签、样式等),可以使用Jsoup库来转换:

  1. 添加Jsoup依赖(Maven):
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.17.2</version>
</dependency>
  1. 修改htmlToPlainText方法:
private String htmlToPlainText(String html) {
    if (html == null || html.isEmpty()) {
        return "";
    }
    return Jsoup.parse(html).text();
}

关键说明

  • 优先读取text/plain是因为很多邮件会同时发送纯文本和HTML两个版本,纯文本版本是专门为不支持HTML的客户端准备的,最准确。
  • 递归处理Multipart是因为有些邮件的内容是嵌套的Multipart结构,单层循环可能无法遍历到所有内容。
  • 正则表达式适合简单HTML的转换,复杂场景下Jsoup的处理更稳定,能保留合理的文本格式(比如段落换行)。

内容的提问来源于stack exchange,提问作者Chirag Manuja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:24:13