如何从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实体(如 、<等) plainText = plainText.replaceAll(" ", " ") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll("&", "&") .replaceAll(""", "\"") .replaceAll("'", "'"); // 3. 移除多余换行和空格 plainText = plainText.replaceAll("\\s+", " ").trim(); return plainText; } }
方法二:使用第三方库处理HTML(更可靠)
如果正则表达式无法处理复杂HTML(比如嵌套标签、样式等),可以使用Jsoup库来转换:
- 添加Jsoup依赖(Maven):
<dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.17.2</version> </dependency>
- 修改
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
相关产品推荐
相关产品推荐

