使用 Java Gmail API 发送包含多个(大)附件的电子邮件

Use Java Gmail API to send an email with multiple (large) attachments

我正在尝试使用 Google Gmail API (Java) 创建包含多个附件的电子邮件。使用下面的代码,我可以发送嵌入在 MimeMessage if 中的多个附件,附件总数小于 5MB(Google的简单文件上传阈值)。

com.google.api.services.gmailGmail service = (... defined above ...)
javax.mail.internet.MimeMessage message = (... defined above with attachments embedded ...)

// Send the email
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
mimeMessage.writeTo(buffer);
byte[] bytes = buffer.toByteArray();
String encodedEmail = Base64.encodeBase64URLSafeString(bytes);
Message message = new Message();
message.setRaw(encodedEmail);

message = service.users().messages().send("me", message).execute();

但是,我无法弄清楚如何使用 Gmail Java API 正确地将多个文件附加到电子邮件中。下面的方法看起来很有希望,但它似乎只接受 1 File/InputStream (mediaContent).

Gmail.Users.Messages.Send send(userId, Message content, AbstractInputStreamContent mediaContent)

有人知道如何使用 API 正确实现多文件上传吗?

如您所述,Simple file upload 的最大附件大小为 5 MB

结论:

您需要使用Multipart upload or Resumable upload

使用分段上传发送电子邮件的示例:

public static MimeMessage createEmailWithAttachment(String to, String from, String subject,
                                      String bodyText,String filePath) throws MessagingException{
    File file = new File(filePath);
    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props, null);
    MimeMessage email = new MimeMessage(session);
    Multipart multipart = new MimeMultipart();
    InternetAddress tAddress = new InternetAddress(to);
    InternetAddress fAddress = new InternetAddress(from);
    email.setFrom(fAddress);
    email.addRecipient(javax.mail.Message.RecipientType.TO, tAddress);
    email.setSubject(subject);
    if (file.exists()) {
        source = new FileDataSource(filePath);
        messageFilePart = new MimeBodyPart();
        messageBodyPart = new MimeBodyPart();
        try {
            messageBodyPart.setText(bodyText);
            messageFilePart.setDataHandler(new DataHandler(source));
            messageFilePart.setFileName(file.getName());

            multipart.addBodyPart(messageBodyPart);
            multipart.addBodyPart(messageFilePart);
            email.setContent(multipart);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }else
        email.setText(bodyText);
    return email;
}

Here 您可以在 Java.

中找到许多其他使用 Gmail API 发送电子邮件的有用示例

事实证明,我的 MimeMessage 已正确生成,但是,如果 MimeMessage 中包含的附件​​大于 5MB,则需要使用不同的 Gmail API send() 方法。 API 文档非常令人困惑,因为它们似乎声明您需要多次调用休息端点以上传多个文件。事实证明,Gmail Java Api 会根据提交的 MimeMessage 为您完成所有工作。

下面的代码片段展示了如何使用这两种方法:"simple upload" 和 "multipart upload"。

com.google.api.services.gmailGmail service = (... defined above ...)
javax.mail.internet.MimeMessage message = (... defined above with attachments embedded ...)

/**
 * Send email using Gmail API - dynamically uses simple or multipart send depending on attachments size
 * 
 * @param mimeMessage MimeMessage (includes any attachments for the email)
 * @param attachments the Set of files that were included in the MimeMessage (if any).  Only used to calculate total size to see if we should use "simple" send or need to use multipart upload.
 */
void send(MimeMessage mimeMessage, @Nullable Set<File> attachments) throws Exception {

    Message message = new Message();
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    mimeMessage.writeTo(buffer);

    // See if we need to use multipart upload
    if (attachments!=null && computeTotalSizeOfAttachments(attachments) > BYTES_5MB) {

        ByteArrayContent content = new ByteArrayContent("message/rfc822", buffer.toByteArray());
        message = service.users().messages().send("me", null, content).execute();

    // Otherwise, use "simple" send
    } else {

        String encodedEmail = Base64.encodeBase64URLSafeString(buffer.toByteArray());
        message.setRaw(encodedEmail);
        message = service.users().messages().send("me", message).execute();
    }

    System.out.println("Gmail Message: " + message.toPrettyString());
}