如何使用javamail将base64图片嵌入电子邮件

6

我正在尝试使用javamail发送带有base64编码的嵌入式图片的电子邮件(img alt='image PNG' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgA...AElFTkSuQmCC'")

当图片很小的时候可以工作,但是当图片较大时,在lotus note中将无法显示图片。

以下是代码的一部分:

Transport transport = mailSession.getTransport();
MimeMessage message = new MimeMessage( mailSession );
message.setSubject( subject );
message.setFrom( new InternetAddress( me) );
message.setContent( bodyWithEmbeddedBase64Image, "text/html" );
transport.connect();
transport.sendMessage( message, message.getAllRecipients() );
transport.close();`

我想使用PreencodedMimeBodyPart来测试,但是我不知道如何使用它。可以有人帮我吗?

3个回答

9

大家好,我找到了答案,不确定我的做法是否正确,但它能够工作。

以下是我的代码:

private static final Pattern imgRegExp  = Pattern.compile( "<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>" );
public send(email) throws Exception{

   Map<String, String> inlineImage = new HashMap<String, String>();
   String body = email.getBody();
   final Matcher matcher = imgRegExp.matcher( body );
   int i = 0;
   while ( matcher.find() ) {
      String src = matcher.group();
      if ( body.indexOf( src ) != -1 ) {
         String srcToken = "src=\"";
         int x = src.indexOf( srcToken );
         int y = src.indexOf( "\"", x + srcToken.length() );
         String srcText = src.substring( x + srcToken.length(), y );
         String cid = "image" + i;
         String newSrc = src.replace( srcText, "cid:" + cid );
         inlineImage.put( cid, srcText.split( "," )[1] );
         body = body.replace( src, newSrc );
         i++;
      }
   }
   Transport transport = mailSession.getTransport();
   MimeMessage message = new MimeMessage( mailSession );
   message.setSubject( email.getObjet() );
   message.setSender( new InternetAddress( email.getSender() ) );
   message.setFrom( new InternetAddress( email.getFrom()) );
   BodyPart bp = new MimeBodyPart();
   bp.setContent( body, "text/html" );
   MimeMultipart mmp = new MimeMultipart();
   mmp.addBodyPart( bp );
   Iterator<Entry<String, String>> it = inlineImage.entrySet().iterator();
   while ( it.hasNext() ) {
      Entry<String, String> pairs = it.next();
      PreencodedMimeBodyPart pmp = new PreencodedMimeBodyPart( "base64" );
      pmp.setHeader( "Content-ID", "<" + pairs.getKey() + ">" );
      pmp.setDisposition( MimeBodyPart.INLINE );
      pmp.setText( pairs.getValue() );
      mmp.addBodyPart( pmp );
   }
   message.setContent( mmp );
   message.addRecipient( Message.RecipientType.TO, new InternetAddress( email.getTo() ) );
   transport.connect();
   transport.sendMessage( message, message.getAllRecipients() );
   transport.close();
}

感谢您的帮助,如果需要改进,请帮忙优化 :)


2
使用pmp.setContent( pairs.getValue(), 'image/png' );比起pmp.setText( pairs.getValue() );更好。 - Jensen Ching

1

由于图像不在单独的正文部分中,PreencodedMimeBodyPart无法帮助您。

您如何对图像进行base64编码?

另一种选择是使用多部分/相关消息,将图像放在单独的部分中,并使用cid: URL引用它。


0

试一下以下代码!

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

import javax.imageio.ImageIO;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;

private File getImgFile(String data, String cid) throws IOException {
    String base64Image = data.split(",")[1];
    byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);

    BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageBytes));

    File outputfile = new File(cid);
    ImageIO.write(img, "jpg", outputfile);
    return outputfile;
}

public Message buildMessageWithEmbeddedImage(Session session) throws MessagingException, IOException {
    SMTPMessage m = new SMTPMessage(session);
    MimeMultipart content = new MimeMultipart("related");

    MimeBodyPart textPart = new MimeBodyPart();
    
    String html = "HTML"; //Your HTML having Base64 Encoded Images
    String[] parts = html.split("src=\"");
    
    Map<String, File> map = new HashMap<>();
    String revisedHTML = parts[0];
    for(int i=1; i<parts.length; i++) {
        String img = parts[i].substring(0, parts[i].indexOf("\""));
        String cid = ContentIdGenerator.getContentId();
        File f = getImgFile(img, cid);
        map.put(cid, f);
        revisedHTML+= "src=\"cid:"+cid+"\" "+parts[i].substring(parts[i].indexOf("\""), parts[i].length());
    }
    textPart.setText(revisedHTML, "US-ASCII", "html");
    content.addBodyPart(textPart);
    
    for (String k : map.keySet()) {
        // Image part
        MimeBodyPart imagePart = new MimeBodyPart();
        imagePart.attachFile(map.get(k));
        imagePart.setContentID("<" + k + ">");
        imagePart.setDisposition(MimeBodyPart.INLINE);
        content.addBodyPart(imagePart);
    }

    m.setContent(content);
    m.setSubject("Your Email Subject");
    return m;
}

注意:图像文件将在您的项目根文件夹中创建,如果您想在发送电子邮件后删除它们,则可以进行删除。但请确保在发送电子邮件后再进行删除。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接