当前位置: 首页 > 知识库问答 >
问题:

如何在java中使用mimemessage类获取电子邮件正文和附件

吕峰
2023-03-14

在我的SMTP服务器代码中,我有一个mimessage实例,我想用它来提取传入的邮件正文(邮件文本)和邮件附件。为此,我在客户端和服务器端使用以下实现。但是,我只能检索邮件附件。代码以某种方式检测CustomerEngineer。ahmet thing两次,都没有包含邮件正文,即:“这是一个邮件正文”。不过我可以检索图像。

在我的java邮件客户端中,我创建了一个具有以下模式的邮件:

try {
        // Create a default MimeMessage object
        Message message = new MimeMessage(session);

        message.setFrom(new InternetAddress(from));

        message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));

        // Set Subject
        message.setSubject("Hi JAXenter");

        BodyPart messageBodyPart = new MimeBodyPart();

        messageBodyPart.setText("This is a message body");

        Multipart multipart = new MimeMultipart();

        multipart.addBodyPart(messageBodyPart);

        DataSource source = new FileDataSource(new File(System.getProperty("user.dir").concat("\\src\\main\\java\\emailrelayserver\\CustomerEngineer.png")));
        messageBodyPart.setDataHandler(new DataHandler(source));
        messageBodyPart.setFileName("CustomerEngineer.ahmet");
        multipart.addBodyPart(messageBodyPart);

        message.setContent(multipart);

        // Send message
        Transport.send(message);

        System.out.println("Sent message successfully....");

    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }

在服务器端,我使用以下逻辑:

 MimeMessage message = new MimeMessage(session, data);

public void seperateBodyAndAttachments(MimeMessage message) throws MessagingException, IOException {
    String mimeType = message.getContentType();
    Date dt = new Date();

    if (message.isMimeType("text/*")) {
        System.out.println("this containst a text file");
    }  else if (message.isMimeType("multipart/*")) {
        Multipart mp = (Multipart) message.getContent();
        int idx = 0;
        int count = mp.getCount();
        for (int i = 0; i < count; i++) {
            BodyPart part = mp.getBodyPart(i);
            String name = part.getDataHandler().getName();
            if (part.isMimeType("text/*")) {
                if (name == null) {
                    name = "text-" + (++idx) + ".txt";
                }
                System.out.println(name);
            } else {
                if (name == null) {
                    name = "attachment-" + (++idx);
                }
                FileOutputStream fos = new FileOutputStream(System.getProperty("user.dir").concat("\\src\\main\\resources\\DevEnvironmentConfigFile\\" + name));
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                part.getDataHandler().writeTo(bos);
                bos.close();
            }
        }
    } else if (message.isMimeType("message/rfc822")) {
        // Not implemented
    } else {
        Object o = message.getContent();
        if (o instanceof String) {
            FileWriter fw = new FileWriter(System.getProperty("user.dir").concat("\\src\\main\\java\\emailrelayserver\\downloads\\"  + "text.txt"));
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write((String)o);
            bw.close();
        } else if (o instanceof InputStream) {
            FileOutputStream fos = new FileOutputStream(System.getProperty("user.dir").concat("\\src\\main\\java\\emailrelayserver\\downloads\\"  +"message.dat"));
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            message.getDataHandler().writeTo(bos);
            bos.close();
        } else {
            FileWriter fw = new FileWriter(System.getProperty("user.dir").concat("\\src\\main\\java\\emailrelayserver\\downloads\\"  +"unknown.txt"));
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write((String)o);
            bw.close();
        }
    }
}

共有2个答案

农英杰
2023-03-14

在我的例子中,我需要从MimeMessage中提取MimeBodyPart。这比我想象的要复杂,但我最终从BouncyCastle上抢走了这两种方法

 /**
 * extract an appropriate body part from the passed in MimeMessage
 */
protected MimeBodyPart makeContentBodyPart(
    MimeMessage message)
    throws SMIMEException
{
    MimeBodyPart content = new MimeBodyPart();
    //
    // add the headers to the body part.
    //
    try
    {
        message.removeHeader("Message-Id");
        message.removeHeader("Mime-Version");

        // JavaMail has a habit of reparsing some content types, if the bodypart is
        // a multipart it might be signed, we rebuild the body part using the raw input stream for the message.
        try
        {
            if (message.getContent() instanceof Multipart)
            {
                content.setContent(message.getRawInputStream(), message.getContentType());
                extractHeaders(content, message);
                return content;
            }
        }
        catch (MessagingException e)
        {
            // fall back to usual method below
        }
        content.setContent(message.getContent(), message.getContentType());
        content.setDataHandler(message.getDataHandler());
        extractHeaders(content, message);
    }
    catch (MessagingException e)
    {
        throw new SMIMEException("exception saving message state.", e);
    }
    catch (IOException e)
    {
        throw new SMIMEException("exception getting message content.", e);
    }

    return content;
}

private void extractHeaders(MimeBodyPart content, MimeMessage message)
    throws MessagingException
{
    Enumeration e = message.getAllHeaders();

    while (e.hasMoreElements())
    {
        Header hdr = (Header)e.nextElement();
        content.addHeader(hdr.getName(), hdr.getValue());
    }
}
柯鸿振
2023-03-14

不太确定你的电子邮件结构。但是请注意,多部分可以嵌套——因此,在搜索身体时,你必须一直向下搜索。而对于mutlipart/alternative,可能会有不止一具尸体。

在你的情况下,你可以看看

multipart/mixed
  multipart/alternative
    text/plain
    text/html
attachment

一种结构。所以第一个多部分实际上不包括主体。考虑一下这段代码:

public void seperateBodyAndAttachments(MimeMessage mm) throws MessagingException, IOException {
   String mimeType = message.getContentType();
   System.out.println("Message is a " + mimeType);  
   Object content = mm.getContent();
   if(content instanceof String) {
     System.out.println("Body: " + content);
   } else if(content instanceof MimeMultipart) {                
     MimeMultipart multi = (MimeMultipart)content;
     System.out.println("We have a "+ multi.getContentType());              
     for(int i = 0; i < multi.getCount(); ++i) {
        BodyPart bo = multi.getBodyPart(i);
        System.out.println("Content "+i+" is a " + bo.getContentType());
        //Now that body part could again be a MimeMultipart...
        Object bodyContent = bo.getContent();
        //possibly build a recurion here -> the logic is the same as for mm.getContent() above
      }
    } else {
        System.out.println("Some other content: " + content.getClass().getName());
    }
}

在你的例子中,混淆源于两次添加身体部位:

    // This is the object created
    BodyPart messageBodyPart = new MimeBodyPart();
    messageBodyPart.setText("This is a message body");

    Multipart multipart = new MimeMultipart();

    // you add a reference to this object into the multipart
    multipart.addBodyPart(messageBodyPart);


    DataSource source = new FileDataSource(new File(System.getProperty("user.dir").concat("\\src\\main\\java\\emailrelayserver\\CustomerEngineer.png")));

    //you CHANGE THE CONTENTS of the object to now contain your attachment
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName("CustomerEngineer.ahmet");

    //and add it a second time.
    multipart.addBodyPart(messageBodyPart);

也许你可以试试这个:

        // Set Subject
        message.setSubject("Hi JAXenter");


        Multipart multipart = new MimeMultipart("mixed");
        //Add Text Part         
        BodyPart textBodyPart = new MimeBodyPart();
        textBodyPart.setContent("This is a message body", "text/plain");
        multipart.addBodyPart(textBodyPart);

        //Add attachment
        DataSource source = new FileDataSource(new File(System.getProperty("user.dir").concat("\\src\\main\\java\\emailrelayserver\\CustomerEngineer.png")));
        BodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setDataHandler(new DataHandler(source));
        messageBodyPart.setFileName("CustomerEngineer.ahmet");
        multipart.addBodyPart(messageBodyPart);

        //Set this as message content
        message.setContent(multipart);



        //This will show you internal structure of your message! D
        message.saveChanges();
        message.writeTo(System.out);

        Transport.send(message);            
 类似资料:
  • 问题内容: 我想从IMAP4服务器获取整个邮件。在python文档中,如果发现此代码有效: 我想知道我是否总是可以相信data [0] [1]返回消息的主体。当我运行“ RFC822.SIZE”时,我只有一个字符串而不是一个元组。 我已经浏览了rfc1730,但无法弄清楚“ RFC822”的正确响应结构。也很难从imaplib文档中得知获取结果的结构。 这是我在获取时得到的: 但是当我获取时,我得

  • 下面的脚本可以将pdf文件作为附件发送到Gmail和Outlook,但不会显示在Yahoo mail中。我的代码怎么了? 其次,当邮件被发送时,除了pdf附件本身,它不会携带邮件正文。任何关于如何添加带有pdf附件的邮件正文的建议都将不胜感激。

  • 问题内容: 我已经尝试通过库成功使用OAuth进行身份验证。 从客户端重定向回后,我发送成功 我发现什么都没有告诉电子邮件部分(为空): 第一个问题 ,如何正确获取电子邮件?无需使用Google+ API。 编辑#2 我尝试将另一个用于: 并尝试使用较新的API检索电子邮件: 但它给 编辑#3 我尝试使用另一个范围: 并尝试使用以下URL检索电子邮件: 但它仍然像以前一样为空。 第二个问题 ,我可

  • 问题内容: 我正在为一个朋友的婚礼编写一个照相馆网络应用程序,他们希望照相馆供客人提交当天拍摄的数码照片。 在评估了所有选项之后,我认为对于用户来说,最简单的事情是让他们使用熟悉的界面(他们的电子邮件),并让他们将图片作为附件发送。 我已经创建了一个邮箱,但是现在我需要连接并检索这些附件以进行自动处理,以添加到图库系统中。但是如何?您是否看到过这样做的任何教程或预制类? 问题答案: 您正在使用什么

  • 在我的服务器上,我不断收到来自gmail的电子邮件... 我收到他们作为MimeMessage类型。 到目前为止,我所做的是用以下方法提取正文: 我现在的问题是,我收到的邮件“回复”了之前的一封邮件。当我为他们的文本提取这些电子邮件时,我收到了“用Y写的X…”然后是之前所有的信件。如何只获取新的回复文本?(没有以前的信件)? 谢谢。

  • 问题内容: 我在使用Gmail PHP API时遇到问题。 我想检索电子邮件的正文内容,但是我只能对具有附件的电子邮件检索它!我的问题是为什么? 到目前为止,这是我的代码: 检索我知道的内容的第二种方法是使用位于“ 标题” 部分中的代码段,但它只能检索50个左右的前字符,这不是很有用。 问题答案: 让我们做一个小实验。我已经给自己发了两条消息。一个带有附件,一个没有附件。 请求: 响应: 我只要求