使用JavaMail在电子邮件中嵌入图像

我想使用javamail发送带有内嵌图像的电子邮件。

我正在做这样的事情。

MimeMultipart content = new MimeMultipart("related"); BodyPart bodyPart = new MimeBodyPart(); bodyPart.setContent(message, "text/html; charset=ISO-8859-1"); content.addBodyPart(bodyPart); bodyPart = new MimeBodyPart(); DataSource ds = new ByteArrayDataSource(image, "image/jpeg"); bodyPart.setDataHandler(new DataHandler(ds)); bodyPart.setHeader("Content-Type", "image/jpeg; name=image.jpg"); bodyPart.setHeader("Content-ID", ""); bodyPart.setHeader("Content-Disposition", "inline"); content.addBodyPart(bodyPart); msg.setContent(content); 

我也试过了

  bodyPart.setHeader("inline; filename=image.jpg"); 

  bodyPart.setDisposition("inline"); 

但无论如何,图像都作为附件发送,内容处理正在变成“附件”。

如何使用javamail在电子邮件中内联发送图像?

你的问题

据我所知,它看起来像你创建消息的方式,一切都是正确的! 您使用正确的MIME类型和所有内容。

我不确定为什么你使用DataSource和DataHandler,并在图像上有ContentID,但是你需要为我完成你的问题才能解决更多问题。 特别是,以下行:

 bodyPart.setContent(message, "text/html; charset=ISO-8859-1"); 

消息是什么? 它包含吗?

您是否尝试使用String cid = ContentIdGenerator.getContentId();生成ContentID String cid = ContentIdGenerator.getContentId(); 而不是使用image


资源

这篇博客文章教我如何使用正确的消息类型,附加我的图像并参考HTML正文中的附件: 如何使用Java发送带有嵌入式图像的电子邮件


细节

信息

您必须使用MimeMultipart类创建内容。 使用字符串"related"作为构造函数的参数非常重要,告诉JavaMail您的部件是“一起工作”

 MimeMultipart content = new MimeMultipart("related"); 

内容标识符

您需要生成ContentID,它是一个字符串,用于标识您附加到电子邮件中的图像,并从电子邮件正文中引用它。

 String cid = ContentIdGenerator.getContentId(); 

注意:此ContentIdGenerator类是假设的。 您可以创建一个或内联创建内容ID。 在我的例子中,我使用一个简单的方法:

 import java.util.UUID; // ... String generateContentId(String prefix) { return String.format("%s-%s", prefix, UUID.randomUUID()); } 

HTML正文

HTML代码是MimeMultipart内容的一部分。 使用MimeBodyPart类。 设置该部分的文本时,不要忘记指定encoding"html"

 MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setText("" + "" + " " + " 

Here is my image:

" + " " + " " + "" ,"US-ASCII", "html"); content.addBodyPart(htmlPart);

请注意,作为图像的来源,我们使用cid:和生成的ContentID。

图片附件

我们可以为图像的附件创建另一个MimeBodyPart

 MimeBodyPart imagePart = new MimeBodyPart(); imagePart.attachFile("resources/teapot.jpg"); imagePart.setContentID("<" + cid + ">"); imagePart.setDisposition(MimeBodyPart.INLINE); content.addBodyPart(imagePart); 

请注意,我们在<>之间使用相同的ContentID,并将其设置为图像的ContentID。 我们还将处置设置为INLINE以表示此图像要显示在电子邮件中,而不是作为附件显示。

完成消息

而已! 如果您在正确的会话上创建SMTP消息并使用该内容,则您的电子邮件将包含嵌入的图像! 例如:

 SMTPMessage m = new SMTPMessage(session); m.setContent(content); m.setSubject("Mail with embedded image"); m.setRecipient(RecipientType.TO, new InternetAddress("your@email.com")); Transport.send(m) 

如果这对您有用,请告诉我! ;)

你为什么不尝试这样的东西?

  MimeMessage mail = new MimeMessage(mailSession); mail.setSubject(subject); MimeBodyPart messageBodyPart = new MimeBodyPart(); messageBodyPart.setContent(message, "text/html"); Multipart multipart = new MimeMultipart(); multipart.addBodyPart(messageBodyPart); messageBodyPart = new MimeBodyPart(); DataSource source = new FileDataSource(new File("complete path to https://stackoverflow.com/questions/2996514/inline-images-in-email-using-javamail/image.jpg")); messageBodyPart.setDataHandler(new DataHandler(source)); messageBodyPart.setFileName(fileAttachment.getName()); messageBodyPart.setDisposition(MimeBodyPart.INLINE); multipart.addBodyPart(messageBodyPart); mail.setContent(multipart); 

在消息中,有一个标签,你应该没问题。

祝你好运

这对我有用:

  MimeMultipart rootContainer = new MimeMultipart(); rootContainer.setSubType("related"); rootContainer.addBodyPart(alternativeMultiPartWithPlainTextAndHtml); // not in focus here rootContainer.addBodyPart(createInlineImagePart(base64EncodedImageContentByteArray)); ... message.setContent(rootContainer); message.setHeader("MIME-Version", "1.0"); message.setHeader("Content-Type", rootContainer.getContentType()); ... BodyPart createInlineImagePart(byte[] base64EncodedImageContentByteArray) throws MessagingException { InternetHeaders headers = new InternetHeaders(); headers.addHeader("Content-Type", "image/jpeg"); headers.addHeader("Content-Transfer-Encoding", "base64"); MimeBodyPart imagePart = new MimeBodyPart(headers, base64EncodedImageContentByteArray); imagePart.setDisposition(MimeBodyPart.INLINE); imagePart.setContentID("<image>"); imagePart.setFileName("http://sofzh.miximages.com/java/image.jpg"); return imagePart; 

如果您使用的是Spring,请使用MimeMessageHelper发送带内联内容的电子邮件( 参考资料 )。

如果您使用的是Spring Boot ,请创建JavaMailSender bean或通过向application.properties文件添加相应的属性来配置它。

 @Bean public JavaMailSender getJavaMailSender() { JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); mailSender.setHost(host); mailSender.setPort(port); mailSender.setUsername(username); mailSender.setPassword(password); Properties props = mailSender.getJavaMailProperties(); props.put("mail.transport.protocol", "smtp"); props.put("mail.smtp.auth", authEnable); props.put("mail.smtp.starttls.enable", starttlsEnable); //props.put("mail.debug", "true"); mailSender.setJavaMailProperties(props); return mailSender; } 

创建算法以生成唯一的CONTENT-ID

 import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Random; public class ContentIdGenerator { static int seq = 0; static String hostname; public static void getHostname() { try { hostname = InetAddress.getLocalHost().getCanonicalHostName(); } catch (UnknownHostException e) { // we can't find our hostname? okay, use something no one else is // likely to use hostname = new Random(System.currentTimeMillis()).nextInt(100000) + ".localhost"; } } /** * Sequence goes from 0 to 100K, then starts up at 0 again. This is large * enough, * and saves * * @return */ public static synchronized int getSeq() { return (seq++) % 100000; } /** * One possible way to generate very-likely-unique content IDs. * * @return A content id that uses the hostname, the current time, and a * sequence number * to avoid collision. */ public static String getContentId() { getHostname(); int c = getSeq(); return c + "." + System.currentTimeMillis() + "@" + hostname; } } 

使用内联发送电子邮件。

 @Autowired private JavaMailSender javaMailSender; public void sendEmailWithInlineImage() { MimeMessage mimeMessage = null; try { InternetAddress from = new InternetAddress(from, personal); mimeMessage = javaMailSender.createMimeMessage(); mimeMessage.setSubject("Test Inline"); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); helper.setFrom(from); helper.setTo("test@test.com"); String contentId = ContentIdGenerator.getContentId(); String htmlText = "Hello, 

This is test with email inlines.

"; helper.setText(htmlText, true); ClassPathResource classPathResource = new ClassPathResource("static/images/first.png"); helper.addInline(contentId, classPathResource); javaMailSender.send(mimeMessage); } catch (Exception e) { LOGGER.error(e.getMessage()); } }

使用以下代码段:

 MimeBodyPart imgBodyPart = new MimeBodyPart(); imgBodyPart.attachFile("Image.png"); imgBodyPart.setContentID('<'+"i01@example.com"+'>'); imgBodyPart.setDisposition(MimeBodyPart.INLINE); imgBodyPart.setHeader("Content-Type", "image/png"); multipart.addBodyPart(imgBodyPart); 

您不需要内联和基本编码 – 您可以传统地附加链接并将链接添加到主消息的text/html类型的text/html
但是请记住在附加到主消息之前(在附加文件之后)将imgBodyPart的标题的Content-Typeimage/jpg左右。

以下是完整的代码

  import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; private BodyPart createInlineImagePart() { MimeBodyPart imagePart =null; try { ByteArrayOutputStream baos=new ByteArrayOutputStream(10000); BufferedImage img=ImageIO.read(new File(directory path,"sdf_email_logo.jpg")); ImageIO.write(img, "jpg", baos); baos.flush(); String base64String=Base64.encode(baos.toByteArray()); baos.close(); byte[] bytearray = Base64.decode(base64String); InternetHeaders headers = new InternetHeaders(); headers.addHeader("Content-Type", "image/jpeg"); headers.addHeader("Content-Transfer-Encoding", "base64"); imagePart = new MimeBodyPart(headers, bytearray); imagePart.setDisposition(MimeBodyPart.INLINE); imagePart.setContentID("<sdf_email_logo>"); imagePart.setFileName("sdf_email_logo.jpg"); } catch(Exception exp) { logError("17", "Logo Attach Error : "+exp); } return imagePart; } MimeMultipart mp = new MimeMultipart(); //mp.addBodyPart(createInlineImagePart()); mp.addBodyPart(createInlineImagePart()); String body="" 

messageBodyPart.setContent(htmlText,“text / html”); multipart.addBodyPart(messageBodyPart);

  messageBodyPart = new MimeBodyPart(); DataSource fds = new FileDataSource("resources/Images/bday.jpg"); messageBodyPart.setDataHandler(new DataHandler(fds)); messageBodyPart.setHeader("Content-ID", ""); // add image to the multipart multipart.addBodyPart(messageBodyPart); msg.setContent(multipart); Transport.send(msg);