9

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....

home
  • 12,468
  • 5
  • 46
  • 54
Konrad Pawlus
  • 1,641
  • 3
  • 14
  • 20

2 Answers2

8

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.

Community
  • 1
  • 1
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • Thanks! So easy... and I lost an hour for solving this :) – Konrad Pawlus Oct 06 '11 at 13:41
  • So... after adding saveChanges call Content Type is lost for body parts ... another one to solve :( – Konrad Pawlus Oct 06 '11 at 14:01
  • @Konrad, I am not 100% sure, but I believe that setContent only accepts the mimetype, not the associated characterset; you may need to use one of the setText methods like http://javamail.kenai.com/nonav/javadocs/javax/mail/internet/MimeMessage.html#setText(java.lang.String,%20java.lang.String,%20java.lang.String). BTW: If all else fails, go to the JavaMail forum on forums.oracle.com : Bill Shannon, the JavaMail developer is very active in answering questions. – Mark Rotteveel Oct 06 '11 at 14:08
  • @Konrad, be sure to link to this question, people on that forum are rather picky when it comes to questions asked elsewhere without a link. – Mark Rotteveel Oct 06 '11 at 14:22
  • Of course ... thanks ... so far I am trying to modify email without loading it into Message object ... I have plain text version of email, and just need to replace and add some text to text/html part ... so maybe it will be faster to do not load it. – Konrad Pawlus Oct 07 '11 at 14:23
  • Just for reference, I asked related question on Oracle forums: https://forums.oracle.com/forums/thread.jspa?threadID=2295329&tstart=0 – Konrad Pawlus Oct 07 '11 at 15:33
  • After much more investigations and reading I found MIME4j http://james.apache.org/mime4j/ and I successfully managed to apply changes in email HTML body using it. Again thanks a lot Mark for your help! – Konrad Pawlus Oct 07 '11 at 22:55
  • @Konrad Can you please give us a sample code of your solution? I have tried following all the links in the discussion thread and now to finish the whole adventure off, it would be great to have a working sample. :) Thank you – elector May 24 '13 at 11:45
0

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);
           }
     }
 }
bobby
  • 2,629
  • 5
  • 30
  • 56