web-dev-qa-db-ja.com

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", "<image>");
bodyPart.setHeader("Content-Disposition", "inline");
content.addBodyPart(bodyPart);

msg.setContent(content);

私も試しました

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

そして

    bodyPart.setDisposition("inline");

ただし、画像は添付ファイルとして送信され、Content-Dispostionは「添付ファイル」に変わります。

Javamailを使用して電子メールで画像をインラインで送信するにはどうすればよいですか?

26
akula1001

あなたの問題

私が見る限り、それはあなたがメッセージを作成する方法のように見え、すべてがほとんど正しいです!適切なMIMEタイプとすべてを使用します。

なぜDataSourceとDataHandlerを使用し、画像にContentIDがあるのか​​わかりませんが、さらにトラブルシューティングできるように質問を完了する必要があります。特に、次の行:

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

messageには何がありますか? _<img src="cid:image" />_が含まれていますか?

imageを使用する代わりにString cid = ContentIdGenerator.getContentId();でContentIDを生成しようとしましたか


ソース

このブログ記事では、適切なメッセージタイプの使用方法、画像の添付方法、HTML本文の添付ファイルの参照方法について説明しました。 Javaを使用して埋め込み画像でメールを送信する方法


詳細

メッセージ

MimeMultipart クラスを使用してコンテンツを作成する必要があります。文字列_"related"_をコンストラクターのパラメーターとして使用して、JavaMailに、パーツが "working together"であることを伝えることが重要です。

_MimeMultipart content = new MimeMultipart("related");
_

コンテンツ識別子

ContentIDを生成する必要があります。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(""
  + "<html>"
  + " <body>"
  + "  <p>Here is my image:</p>"
  + "  <img src=\"cid:" + cid + "\" />"
  + " </body>"
  + "</html>" 
  ,"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("[email protected]"));
Transport.send(m)
_

それがあなたのために働くかどうか私に知らせてください! ;)

33
snooze92

これは私のために働いた:

  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("&lt;image&gt;");
    imagePart.setFileName("image.jpg");
    return imagePart;
10
Jörg Pfründer

このようなものを試してみませんか?

    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 image.jpg"));
    messageBodyPart.setDataHandler(new DataHandler(source));
    messageBodyPart.setFileName(fileAttachment.getName());
    messageBodyPart.setDisposition(MimeBodyPart.INLINE);
    multipart.addBodyPart(messageBodyPart);

    mail.setContent(multipart);

メッセージには、<img src="image.jpg"/>タグを付ければ大丈夫です。

幸運を

10
Bernardo

RFC仕様はここにあります( https://tools.ietf.org/html/rfc2392 )。

まず、インライン画像を使用する場合、HTMLコンテンツの形式は「cid:logo.png」のような形式にする必要があります。以下を参照してください。

<td style="width:114px;padding-top: 19px">
    <img src="cid:logo.png" />
</td>

次に、MimeBodyPartオブジェクトは、以下のように、プロパティ「disposition」をMimeBodyPart.INLINEとして設定する必要があります。

String filename = "logo.png"
BodyPart image = new MimeBodyPart();
image.setDisposition(MimeBodyPart.INLINE);
image.setFileName(filename);
image.setHeader("Content-ID", "<" +filename+">");

Content-IDプロパティは、「<」および「>」を前と後ろに付ける必要があることに注意してください。 : "

最後に、コード全体を以下に示します。

Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("[email protected]");
InternetAddress[] recipients = { "[email protected]"};
msg.setRecipients(Message.RecipientType.TO, recipients);
msg.setSubject("for test");
msg.setSentDate(new Date());

BodyPart content = new MimeBodyPart();
content.setContent(<html><body>  <img src="cid:logo.png" /> </body></html>, "text/html; charset=utf-8");
String fileName = "logo.png";
BodyPart image = new MimeBodyPart();
image.setHeader("Content-ID", "<" +fileName+">");
image.setDisposition(MimeBodyPart.INLINE);
image.setFileName(fileName);
InputStream stream = MailService.class.getResourceAsStream(path);
DataSource fds = new ByteArrayDataSource(IOUtils.toByteArray(stream), "image/png");
image.setDataHandler(new DataHandler(fds));

MimeMultipart multipart = new MimeMultipart("related");
multipart.addBodyPart(content);
multipart.addBodyPart(getImage(image1));
msg.setContent(multipart);
msg.saveChanges();
Transport bus = session.getTransport("smtp");
bus.connect("username", "password");
bus.sendMessage(msg, recipients);
bus.close();
1
Jackie Yu

GMailとThunderbirdでインライン画像を表示する際にいくつかの問題が発生し、いくつかのテストを行い、次の(サンプル)コードで解決しました。

String imagePath = "/path/to/the/image.png";
String fileName = imagePath.substring(path.lastIndexOf('/') + 1);
String htmlText = "<html><body>TEST:<img src=\"cid:img1\"></body></html>";
MimeMultipart multipart = new MimeMultipart("related");
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(htmlText, "text/html; charset=utf-8");
multipart.addBodyPart(messageBodyPart);
messageBodyPart = new MimeBodyPart();
DataSource fds = new FileDataSource(imagePath);
messageBodyPart.setDataHandler(new DataHandler(fds));
messageBodyPart.setHeader("Content-ID", "<img1>");
messageBodyPart.setDisposition(MimeBodyPart.INLINE);
messageBodyPart.setFileName(fileName);
multipart.addBodyPart(messageBodyPart);
message.setContent(multipart);

注目すべきいくつかのこと:

  • 「Content-ID」はRFC( https://tools.ietf.org/html/rfc2392 )で指定されたとおりに構築する必要があるため、imgタグsrcの一部である必要があります山括弧( "<"および ">")で囲まれた "cid:"に続く属性
  • ファイル名を設定する必要がありました
  • imgタグに幅、高さ、altまたはタイトルは必要ありません
  • HTMLの文字セットは無視されていたため、文字セットをそのように配置する必要がありました

これは、一部のクライアントとGMail Webクライアントでインライン画像を表示するのに役立ちましたが、これがどこでも永遠に機能するというわけではありません! :)

(私の英語とタイプミスのために申し訳ありません!)

0
debbbole

以下は完全なコードです

    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("&lt;sdf_email_logo&gt;");
        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="<img src=\"cid:sdf_email_logo\"/>"
0
user1517878

次のスニペットを使用します。

MimeBodyPart imgBodyPart = new MimeBodyPart();
imgBodyPart.attachFile("Image.png");
imgBodyPart.setContentID('<'+"[email protected]"+'>');
imgBodyPart.setDisposition(MimeBodyPart.INLINE);
imgBodyPart.setHeader("Content-Type", "image/png");

multipart.addBodyPart(imgBodyPart);

インラインおよびベースエンコードは不要です。従来の方法で添付し、text/htmlタイプのメインメッセージのテキストにリンクを追加できます。
ただし、imgBodyPartのヘッダーのContent-Typeimage/jpgなどに設定してから、メインメッセージに追加する直前(ファイルを添付した後)に設定してください。

0
Ujjwal Singh