Konrad Pawlus
Konrad Pawlus

Reputation: 1710

How to modify existing Java mail MimeMessage body parts?

I am trying to modify existing MimeMessage body part. I would like to filter certain links. Does any of you know why even though body part content seams to be changed message is sent with old content? Is there some caching going on? Any idea how to solve this?

Here is my code:

public void resend(InputStream data) throws Exception {
    Session mailSession = createMailSession();
    //mailSession.setDebug(true);

    Transport transport = mailSession.getTransport();
    MimeMessage message = new MimeMessage(mailSession, data);

    Object content = message.getContent();
    if (content.getClass().isAssignableFrom(MimeMultipart.class)) {
        MimeMultipart mimeMultipart = (MimeMultipart) content;

        for (int i = 0; i < mimeMultipart.getCount(); i++) {

            BodyPart bodyPart = mimeMultipart.getBodyPart(i);
            if (bodyPart.getContentType().startsWith("text/plain")) {
                String cnt = updateContent((String) bodyPart.getContent());
                System.out.println("ContentType = " + bodyPart.getContentType());
                System.out.println("Content = " + cnt);

                bodyPart.setContent(cnt, bodyPart.getContentType());
            } else if (bodyPart.getContentType().startsWith("text/html")) {
                String cnt = updateContent((String) bodyPart.getContent());
                System.out.println("ContentType = " + bodyPart.getContentType());
                System.out.println("Content = " + cnt);

                bodyPart.setContent(cnt, bodyPart.getContentType());
            }
        }
    } else {
        String cnt = updateContent((String) message.getContent());
        System.out.println("ContentType = " + message.getContentType());
        System.out.println("Content = " + cnt);

        message.setContent(cnt, message.getContentType());
    }

    transport.connect();
    transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
    transport.close();
}

private String updateContent(String cnt) {
    return cnt.replace("www.xyz.pl", "www.new-xyz.pl");
}

Input stream "data" contains raw message.

Any ideas?

Thanks in advance....

Upvotes: 9

Views: 10403

Answers (2)

bobby
bobby

Reputation: 2789

To update both the text/plain and text/html sections, I used functionalities provided by Jsoup

     MimeMessage message = new MimeMessage(mailSession, data);
     String newText ="Whatever you want";
     updateText(message);
     message.saveChanges();


 private void updateText(String newText, MimePart part){

     if the mime type is "text/plain"{
            part.setText(newText, "UTF-8");
     }else if the mime type is "text/html"{
           String html = (String) part.getContent();
           Document document = Jsoup.parse(html)
           Element body = doc.body();
           body.text(newText);
           part.setContent(doc.html(), "text/html;charset=UTF-8");
     }else if the mime type is multipart/*{
           Multipart multi = (Multipart) part.getContent();
           int count = multi.getCount();
           for (int i = 0; i < count; i++) {
               updateText(newText, multi.getbodyPart(i);
           }
     }
 }

Upvotes: 0

Mark Rotteveel
Mark Rotteveel

Reputation: 108994

You need to call saveChanges() on the MimeMessage (which as far as I know should be sufficient), see also: api-doc MimeMessage#saveChanges():

Updates the appropriate header fields of this message to be consistent with the message's contents. If this message is contained in a Folder, any changes made to this message are committed to the containing folder.

If any part of a message's headers or contents are changed, saveChanges must be called to ensure that those changes are permanent. Otherwise, any such modifications may or may not be saved, depending on the folder implementation.

Upvotes: 8

Related Questions