1

我有一个托管在 AWS 上的 Spring Boot 应用程序。我正在使用 AWS SES 来触发电子邮件。但我不知道如何使用 SES 附加图像。我使用 JAVA 作为应用程序源代码。数据存储在数据库中,但未发送电子邮件。:


   public void sendEmail(String to, String subject, String body) throws MessagingException {
        Properties props = System.getProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.port", PORT);
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.auth", "true");

        Session session = Session.getDefaultInstance(props);

        Message msg = new MimeMessage(session);
        MimeMultipart multipart = new MimeMultipart();
        BodyPart messageBodyPart = new MimeBodyPart();
        // the body content:
        messageBodyPart.setContent(BODY, "text/html");
        multipart.addBodyPart(messageBodyPart);
        // the image:
        messageBodyPart = new MimeBodyPart();
        DataSource fds = new FileDataSource(
                "Logo.png");
        messageBodyPart.setDataHandler(new DataHandler(fds));
        messageBodyPart.setHeader("Content-ID", "<image_01>");
        multipart.addBodyPart(messageBodyPart);
        // add the multipart to the message:
        msg.setContent(multipart);
        // set the remaining values as usual:
        try {
            msg.setFrom(new InternetAddress(FROM, FROMNAME));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (MessagingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
        msg.setSubject(SUBJECT);

        Transport transport = session.getTransport();

        try {
            System.out.println("Sending...");
            transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
            transport.sendMessage(msg, msg.getAllRecipients());
            System.out.println("Email sent!");
        } catch (Exception ex) {
            System.out.println("The email was not sent.");
            ex.printStackTrace();
        } finally {
            transport.close();
        }
    }

项目结构错误 日志

4

2 回答 2

2

要将图像嵌入到您的电子邮件中,您需要对代码进行一些更改。我使用 SES 帐户、JavaMail 和 gmail Web 客户端测试了这些更改:

使用内容 ID 方案 ( cid:)

这是您使用的正文内容cid

static final String BODY = String.join(System.getProperty("line.separator"),
    "<html><head></head><body><img src=\"cid:image_01\"></html> <br>"
    + "Welcome to ABC and have a great experience.");

在这个例子中,image_01是我想使用的任何标识符。当显示邮件时,该cid:方案意味着电子邮件客户端将在邮件中查找Content-ID标题,并使用该名称检索相关图像 - 但名称需要用尖括号括起来<>内联显示(见下文)。

在此处查看更多信息。

创建多部分 Mime 消息

您的MimeMessage msg对象将需要以不同的方式构建:

Message msg = new MimeMessage(session);
MimeMultipart multipart = new MimeMultipart();
try {
    BodyPart messageBodyPart = new MimeBodyPart();
    // the body content:
    messageBodyPart.setContent(BODY, "text/html");
    multipart.addBodyPart(messageBodyPart);
    // the image:
    messageBodyPart = new MimeBodyPart();
    DataSource fds = new FileDataSource("/your/path/to/logo.png");
    messageBodyPart.setDataHandler(new DataHandler(fds));
    messageBodyPart.setHeader("Content-ID", "<image_01>");
    multipart.addBodyPart(messageBodyPart);
    // add the multipart to the message:
    msg.setContent(multipart);
    // set the remaining values as usual:
    msg.setFrom(new InternetAddress(FROM, FROMNAME));
    msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
    msg.setSubject(SUBJECT);
} catch (UnsupportedEncodingException | MessagingException ex) {
    Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}

在这里,我们构建一个由两部分组成的消息:

  1. 来自的 HTML 内容BODY
  2. 图片。

在我的示例中,图像是文件系统上的一个文件——但您可以通过应用程序所需的任何方式访问它(例如通过资源)。

注意设置标题时使用尖括号(如前所述):

messageBodyPart.setHeader("Content-ID", "<image_01>");

现在您可以按通常的方式发送消息:

try ( Transport transport = session.getTransport()) {
    System.out.println("Sending...");
    transport.connect(HOST, SMTP_USERNAME, SMTP_PASSWORD);
    transport.sendMessage(msg, msg.getAllRecipients());
    System.out.println("Email sent!");
} catch (Exception ex) {
    Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}

关于JavaMailSender

在您的代码中,您包含以下内容:

private JavaMailSender mailSender;

这是 Spring 对 JavaMail(现在的 JakartaMail)对象的包装。您没有在代码中使用此对象。

鉴于您使用的是 Spring,我建议您使用上述方法,然后重构您的代码以使用 Spring 的邮件帮助程序实用程序。有很多其他的指南和教程。

关于 SES 的说明

上述方法是使用亚马逊的SES SMTP 接口。换句话说,您的代码中不需要任何 Amazon SDK 类。

这是我在测试此答案中的代码时使用的(使用 SES 帐户)。

您当然可以考虑使用此处此处记录的其他两种方法中的任何一种- 但显示图像都不需要。


更新

为了澄清,有人问了这个问题:

messageBodyPart.setHeader("Content-ID", "<image_01>");

文本<image_01>是您在 HTML 代码中引用图像的方式。所以,这就是我的示例代码使用它的原因:

<img src=\"cid:image_01\">

您可以在此处使用所需的任何标识符。在我的例子中,标识符“image_01”是指我的图像文件“logo.png”。

但要明确一点 - 您确实需要在代码中包含 the<和 the >。它们在我的代码中不仅仅是“占位符”——它们是您需要使用的语法的一部分。


但请记住,如果您充分利用 Spring 和Spring Mail Helper 功能,您可以让一切变得更简单。

例如,这是相同的方法,使用 Spring 的JavaMailSenderand MimeMessageHelper

import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

@Component
public class MySpringMailer {

    static final String FROM = "donotreply@myaddress.com";
    static final String FROMNAME = "My Name";
    static final String TO = "my.email@myaddress.com";
    static final String SUBJECT = "Welcome to ABC";
    static final String BODY = String.join(System.getProperty("line.separator"),
            "<html><head></head><body><img src=\"cid:image_01\"></html> <br>"
            + "Welcome to ABC and have a really great experience.");

    @Autowired
    private JavaMailSender javaMailSender;

    public void sendSpringEmailWithInlineImage() {
        MimeMessage msg = javaMailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(msg, true); // true = multipart
            helper.setFrom(FROM, FROMNAME);
            helper.setTo(TO);
            helper.setSubject(SUBJECT);
            helper.setText(BODY, true); // true = HTML
            DataSource res = new FileDataSource("c:/tmp/logo.png");
            helper.addInline("image_01", res);
        } catch (UnsupportedEncodingException | MessagingException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }
        javaMailSender.send(msg);
    }

}

因此,例如,现在我们可以使用以下方法为我们的图像文件创建一个引用:

helper.addInline("image_01", res);

请注意,当我们在 Java 代码中定义名称时,Spring 不需要我们在这里使用<和。>Spring 在幕后为我们解决了这个问题。

于 2020-08-29T15:55:56.350 回答
0

以下是通过 SES 发送电子邮件的示例代码,其中嵌入了图像作为附件:

    String filePath = "src/main/resources/" + barcodeText + ".png";
    System.out.println("barcodeImg was saved in System locally");

    String subject = "test subject";
    String body = "<!DOCTYPE html>\n" + "<html>\n" + "    <head>\n" + "        <meta charset=\"utf-8\">\n"
            + "        <title></title>\n" + "    </head>\n" + "    <body>\n" + "        <p>test</p>\n"
            + "        <p>-- BarCode from attachment<br><img src=\"cid:barcode\"></p><br>BarCode render completed\n"
            + "    </body>\n" + "</html>";
    String toAddrsStr = "emailID1, emailID2, emailID3";
    sendEmailWithAttachment(toAddrsStr, subject, body, filePath);

定义:

public static void sendEmailWithAttachment(String to, String subject, String body, String attachmentFilePath) {
    Session session = Session.getDefaultInstance(new Properties());
    MimeMessage message = new MimeMessage(session);
    try {
        message.setSubject(subject, "UTF-8");
        message.setFrom(new InternetAddress("gowthamdpt@gmail.com"));
        //to address String should be with comma separated.
        message.setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(to));

        MimeMultipart msg = new MimeMultipart("alternative");
        MimeBodyPart wrap = new MimeBodyPart();
        MimeMultipart msgBody = new MimeMultipart("mixed");

        MimeBodyPart htmlPart = new MimeBodyPart();
        htmlPart.setContent(body, "text/html; charset=UTF-8");
        msgBody.addBodyPart(htmlPart);
        wrap.setContent(msgBody);
        msg.addBodyPart(wrap);

        MimeBodyPart att = new MimeBodyPart();
        DataSource fds = new FileDataSource(attachmentFilePath);
        att.setDataHandler(new DataHandler(fds));
        att.setFileName(fds.getName());
        att.setContentID("<barcode>");
        msg.addBodyPart(att);
        message.setContent(msg);

        AmazonSimpleEmailService client = AmazonSimpleEmailServiceClientBuilder.standard()
                .withRegion(Regions.US_EAST_1).build();
        message.writeTo(System.out);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        message.writeTo(outputStream);
        RawMessage rawMessage = new RawMessage(ByteBuffer.wrap(outputStream.toByteArray()));
        SendRawEmailRequest rawEmailRequest = new SendRawEmailRequest(rawMessage)
                .withConfigurationSetName(CONFIGSET);
        client.sendRawEmail(rawEmailRequest);
        System.out.println("sendEmail()" + "email triggered successfully");
    } catch (Exception ex) {
        System.out.println("sendEmail()" + "The email was not sent. Error: " + ex.getMessage());
    }
}
于 2021-07-12T08:43:32.947 回答