我正在使用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()
会返回一个对象,因为内容可能是String
,MimeMultiPart
,SharedByteArrayInputstream
和其他(我认为)......有没有办法让消息体内的文本始终存在?谢谢!!
答案 0 :(得分:55)
此答案延伸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;
}
答案 1 :(得分:17)
此答案延伸Austin's answer以纠正处理multipart/alternative
(// without break same text appears twice in my tests
)的原始问题。
文字显示两次,因为对于multipart/alternative
,用户代理只能选择一个部分。
来自RFC2046:
&#34; multipart / alternative&#34; type在语法上与&#34; multipart / mixed&#34;相同,但语义不同。特别是,每个身体部位都是一个替代品。版本相同的信息。
系统应该认识到各个部分的内容是可以互换的。系统应该选择最好的&#34;基于本地环境和引用的类型,在某些情况下甚至通过用户交互。与&#34; multipart / mixed&#34;一样,身体部位的顺序很重要。在这种情况下,替代方案以对原始内容的忠诚度增加的顺序出现。通常,最佳选择是接收系统的本地环境支持的类型的最后部分。
替代方案处理的相同例子:
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;
}
请注意,这是一个非常简单的示例。它错过了很多案例,不应该以当前的格式用于制作。
答案 2 :(得分:10)
以下是在bodyParts为text和html的情况下从消息中获取文本的方法。
{{1}}
<强>更新即可。有一种情况,bodyPart本身可以是multipart类型。 (在写完这个答案之后我遇到了这样的电子邮件。)在这种情况下,你需要用递归重写上面的方法。
答案 3 :(得分:9)
我不这么认为,否则如果Part
的mime类型为image/jpeg
会怎样? API返回Object
,因为在内部它会尝试为您提供有用的内容,前提是您知道预期的内容。对于通用软件,它的用途如下:
if (part.isMimeType("text/plain")) {
...
} else if (part.isMimeType("multipart/*")) {
...
} else if (part.isMimeType("message/rfc822")) {
...
} else {
...
}
你也有原始的(实际上不是那么原始,请参阅Javadoc)Part.getInputStream()
,但我认为假设你收到的每条消息都是基于文本的是不安全的一个 - 除非您正在编写一个非常具体的应用程序,并且您可以控制输入源。
答案 4 :(得分:4)
如果你想总是得到文本,那么你可以跳过其他类型,比如'multipart'等......
Object body = message.getContent();
if(body instanceof String){
// hey it's a text
}
答案 5 :(得分:1)
不要重新发明轮子!您可以简单地使用Apache Commons Email(请参阅here)
Kotlin示例:
fun readHtmlContent(message: MimeMessage) =
MimeMessageParser(message).parse().htmlContent
如果电子邮件不包含html内容,但包含简单内容(您可以通过hasPlainContent和hasHtmlContent方法进行检查),则应使用以下代码:
fun readPlainContent(message: MimeMessage) =
MimeMessageParser(message).parse().plainContent
Java示例:
String readHtmlContent(MimeMessage message) throws Exception {
return new MimeMessageParser(message).parse().getHtmlContent();
}
String readPlainContent(MimeMessage message) throws Exception {
return new MimeMessageParser(message).parse().getPlainContent();
}
答案 6 :(得分:0)
我的答案是Austin Answer的扩展版本,但第一种方法(getTextFromMessage())有一个条件。
更改:我们还应该检查MimeType是否为“ text / html”。
检查以'// '**
结尾的行private String getTextFromMessage(Message message) throws MessagingException, IOException {
String result = "";
if (message.isMimeType("text/plain")) {
result = message.getContent().toString();
}
else if (message.isMimeType("text/html")) { // **
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;
}
答案 7 :(得分:0)
您可以使用org.apache.commons.mail.util.MimeMessageParser
Java:
String htmlContent = new MimeMessageParser(message).parse().getHtmlContent();
科特琳:
val htmlContent: String = MimeMessageParser(message).parse().htmlContent
答案 8 :(得分:0)
在我的情况下,我希望HTML也存在,并且我还搜索了一些已经实现的实用性,因此我使用以下代码修复了我的问题
import javax.mail.Message;
import org.apache.commons.io.IOUtils;
import javax.mail.internet.MimeUtility;
.....
String body = IOUtils.toString(
MimeUtility.decode(message.getInputStream(), "quoted-printable"), "UTF-8");
答案 9 :(得分:0)
这是我的代码,我在IMAP android应用程序中使用。它的工作。
GetTextFromMessage返回纯文本或html字符串
科特琳
@Throws(IOException::class, MessagingException::class)
private fun getTextFromMessage(message: Message): String {
var result: String = ""
if (message.isMimeType("text/plain")) {
result = message.content.toString()
}
else if (message.isMimeType("multipart/*")) {
val mimeMultipart =
message.content as MimeMultipart
result = getTextFromMimeMultipart(mimeMultipart)
}
else if(message.isMimeType("text/html")){
result = message.content.toString()
}
return result
}
@Throws(IOException::class, MessagingException::class)
private fun getTextFromMimeMultipart(
mimeMultipart: MimeMultipart
): String {
val count = mimeMultipart.count
if (count == 0) throw MessagingException("Multipart with no body parts not supported.")
val multipartRelated = ContentType(mimeMultipart.contentType).match("multipart/related")
if(multipartRelated){
val part = mimeMultipart.getBodyPart(0)
val multipartAlt = ContentType(part.contentType).match("multipart/alternative")
if(multipartAlt) {
return getTextFromMimeMultipart(part.content as MimeMultipart)
}
}else{
val multipartAlt = ContentType(mimeMultipart.contentType).match("multipart/alternative")
if (multipartAlt) {
for (i in 0 until count) {
val part = mimeMultipart.getBodyPart(i)
if (part.isMimeType("text/html")) {
return getTextFromBodyPart(part)
}
}
}
}
var result: String = ""
for (i in 0 until count) {
val bodyPart = mimeMultipart.getBodyPart(i)
result += getTextFromBodyPart(bodyPart)
}
return result
}
@Throws(IOException::class, MessagingException::class)
private fun getTextFromBodyPart(
bodyPart: BodyPart
): String {
var result: String = ""
if (bodyPart.isMimeType("text/plain")) {
result = bodyPart.content as String
} else if (bodyPart.isMimeType("text/html")) {
val html = bodyPart.content as String
result = html
} else if (bodyPart.content is MimeMultipart) {
result =
getTextFromMimeMultipart(bodyPart.content as MimeMultipart)
}
return result
}