📄 mimemessagehelper.java
字号:
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.mail.javamail;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.FileTypeMap;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
import org.springframework.core.io.InputStreamSource;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
/**
* Helper class for easy population of a <code>javax.mail.internet.MimeMessage</code>.
*
* <p>Mirrors the simple setters of SimpleMailMessage, directly applying the values
* to the underlying MimeMessage. Allows to define a character encoding for the
* entire message, automatically applied by all methods of this helper.
*
* <p>Offers support for HTML text content, inline elements such as images, and typical
* mail attachments. Also supports personal names that accompany mail addresses. Note that
* advanced settings can still be applied directly to the underlying MimeMessage object!
*
* <p>Typically used in MimeMessagePreparator implementations or JavaMailSender
* client code: simply instantiating it as a MimeMessage wrapper, invoking
* setters on the wrapper, using the underlying MimeMessage for mail sending.
* Also used internally by JavaMailSenderImpl.
*
* <p>Sample code for an HTML mail with an inline image and a PDF attachment:
*
* <pre>
* mailSender.send(new MimeMessagePreparator() {
* public void prepare(MimeMessage mimeMessage) throws MessagingException {
* MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
* message.setFrom("me@mail.com");
* message.setTo("you@mail.com");
* message.setSubject("my subject");
* message.setText("my text <img src='cid:myLogo'>", true);
* message.addInline("myLogo", new ClassPathResource("img/mylogo.gif"));
* message.addAttachment("myDocument.pdf", new ClassPathResource("doc/myDocument.pdf"));
* }
* });</pre>
*
* Consider using MimeMailMessage (which implements the common MailMessage
* interface, just like SimpleMailMessage) on top of a MimeMessageHelper,
* to let message population code interact with a simple message or a MIME
* message through a common interface.
*
* <p><b>Warning regarding multipart mails:</b> Simple MIME messages that
* just contain HTML text but no inline elements or attachments will work on
* more or less any email client that is capable of HTML rendering. However,
* inline elements and attachments are still a major compatibility issue
* between email clients: It's virtually impossible to get inline elements
* and attachments working across Microsoft Outlook, Lotus Notes and Mac Mail.
* Consider choosing a specific multipart mode for your needs: The javadoc
* on the MULTIPART_MODE constants contains more detailed information.
*
* @author Juergen Hoeller
* @since 19.01.2004
* @see #setText(String, boolean)
* @see #setText(String, String)
* @see #addInline(String, org.springframework.core.io.Resource)
* @see #addAttachment(String, org.springframework.core.io.InputStreamSource)
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int)
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int, String)
* @see #MULTIPART_MODE_MIXED_RELATED
* @see #MULTIPART_MODE_RELATED
* @see #getMimeMessage
* @see MimeMessagePreparator
* @see JavaMailSender
* @see javax.mail.internet.MimeMessage
* @see org.springframework.mail.SimpleMailMessage
* @see MimeMailMessage
*/
public class MimeMessageHelper {
/**
* Constant indicating a non-multipart message.
*/
public static final int MULTIPART_MODE_NO = 0;
/**
* Constant indicating a multipart message with a single root multipart
* element of type "mixed". Texts, inline elements and attachements
* will all get added to that root element.
* <p>This was Spring 1.0's default behavior. It is known to work properly
* on Outlook. However, other mail clients tend to misinterpret inline
* elements as attachments and/or show attachments inline as well.
*/
public static final int MULTIPART_MODE_MIXED = 1;
/**
* Constant indicating a multipart message with a single root multipart
* element of type "related". Texts, inline elements and attachements
* will all get added to that root element.
* <p>This was the default behavior from Spring 1.1 up to 1.2 final.
* This is the "Microsoft multipart mode", as natively sent by Outlook.
* It is known to work properly on Outlook, Outlook Express, Yahoo Mail, and
* to a large degree also on Mac Mail (with an additional attachment listed
* for an inline element, despite the inline element also shown inline).
* Does not work properly on Lotus Notes (attachments won't be shown there).
*/
public static final int MULTIPART_MODE_RELATED = 2;
/**
* Constant indicating a multipart message with a root multipart element
* "mixed" plus a nested multipart element of type "related". Texts and
* inline elements will get added to the nested "related" element,
* while attachments will get added to the "mixed" root element.
* <p>This is the default since Spring 1.2.1. This is arguably the most correct
* MIME structure, according to the MIME spec: It is known to work properly
* on Outlook, Outlook Express, Yahoo Mail, and Lotus Notes. Does not work
* properly on Mac Mail. If you target Mac Mail or experience issues with
* specific mails on Outlook, consider using MULTIPART_MODE_RELATED instead.
*/
public static final int MULTIPART_MODE_MIXED_RELATED = 3;
private static final String MULTIPART_SUBTYPE_MIXED = "mixed";
private static final String MULTIPART_SUBTYPE_RELATED = "related";
private static final String MULTIPART_SUBTYPE_ALTERNATIVE = "alternative";
private static final String CONTENT_TYPE_ALTERNATIVE = "text/alternative";
private static final String CONTENT_TYPE_HTML = "text/html";
private static final String CONTENT_TYPE_CHARSET_SUFFIX = ";charset=";
private static final String HEADER_CONTENT_ID = "Content-ID";
private final MimeMessage mimeMessage;
private MimeMultipart rootMimeMultipart;
private MimeMultipart mimeMultipart;
private final String encoding;
private FileTypeMap fileTypeMap;
private boolean validateAddresses = false;
/**
* Create a new MimeMessageHelper for the given MimeMessage,
* assuming a simple text message (no multipart content,
* i.e. no alternative texts and no inline elements or attachments).
* <p>The character encoding for the message will be taken from
* the passed-in MimeMessage object, if carried there. Else,
* JavaMail's default encoding will be used.
* @param mimeMessage MimeMessage to work on
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, boolean)
* @see #getDefaultEncoding(javax.mail.internet.MimeMessage)
* @see JavaMailSenderImpl#setDefaultEncoding
*/
public MimeMessageHelper(MimeMessage mimeMessage) {
this(mimeMessage, null);
}
/**
* Create a new MimeMessageHelper for the given MimeMessage,
* assuming a simple text message (no multipart content,
* i.e. no alternative texts and no inline elements or attachments).
* @param mimeMessage MimeMessage to work on
* @param encoding the character encoding to use for the message
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, boolean)
*/
public MimeMessageHelper(MimeMessage mimeMessage, String encoding) {
this.mimeMessage = mimeMessage;
this.encoding = (encoding != null ? encoding : getDefaultEncoding(mimeMessage));
this.fileTypeMap = getDefaultFileTypeMap(mimeMessage);
}
/**
* Create a new MimeMessageHelper for the given MimeMessage,
* in multipart mode (supporting alternative texts, inline
* elements and attachments) if requested.
* <p>Consider using the MimeMessageHelper constructor that
* takes a multipartMode argument to choose a specific multipart
* mode other than MULTIPART_MODE_MIXED_RELATED.
* <p>The character encoding for the message will be taken from
* the passed-in MimeMessage object, if carried there. Else,
* JavaMail's default encoding will be used.
* @param mimeMessage MimeMessage to work on
* @param multipart whether to create a multipart message that
* supports alternative texts, inline elements and attachments
* (corresponds to MULTIPART_MODE_MIXED_RELATED)
* @throws MessagingException if multipart creation failed
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int)
* @see #getDefaultEncoding(javax.mail.internet.MimeMessage)
* @see JavaMailSenderImpl#setDefaultEncoding
*/
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart) throws MessagingException {
this(mimeMessage, multipart, null);
}
/**
* Create a new MimeMessageHelper for the given MimeMessage,
* in multipart mode (supporting alternative texts, inline
* elements and attachments) if requested.
* <p>Consider using the MimeMessageHelper constructor that
* takes a multipartMode argument to choose a specific multipart
* mode other than MULTIPART_MODE_MIXED_RELATED.
* @param mimeMessage MimeMessage to work on
* @param multipart whether to create a multipart message that
* supports alternative texts, inline elements and attachments
* (corresponds to MULTIPART_MODE_MIXED_RELATED)
* @param encoding the character encoding to use for the message
* @throws MessagingException if multipart creation failed
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int, String)
*/
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, String encoding)
throws MessagingException {
this(mimeMessage, (multipart ? MULTIPART_MODE_MIXED_RELATED : MULTIPART_MODE_NO), encoding);
}
/**
* Create a new MimeMessageHelper for the given MimeMessage,
* in multipart mode (supporting alternative texts, inline
* elements and attachments) if requested.
* <p>The character encoding for the message will be taken from
* the passed-in MimeMessage object, if carried there. Else,
* JavaMail's default encoding will be used.
* @param mimeMessage MimeMessage to work on
* @param multipartMode which kind of multipart message to create
* (MIXED, RELATED, MIXED_RELATED, or NO)
* @throws MessagingException if multipart creation failed
* @see #MULTIPART_MODE_NO
* @see #MULTIPART_MODE_MIXED
* @see #MULTIPART_MODE_RELATED
* @see #MULTIPART_MODE_MIXED_RELATED
* @see #getDefaultEncoding(javax.mail.internet.MimeMessage)
* @see JavaMailSenderImpl#setDefaultEncoding
*/
public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode) throws MessagingException {
this(mimeMessage, multipartMode, null);
}
/**
* Create a new MimeMessageHelper for the given MimeMessage,
* in multipart mode (supporting alternative texts, inline
* elements and attachments) if requested.
* @param mimeMessage MimeMessage to work on
* @param multipartMode which kind of multipart message to create
* (MIXED, RELATED, MIXED_RELATED, or NO)
* @param encoding the character encoding to use for the message
* @throws MessagingException if multipart creation failed
* @see #MULTIPART_MODE_NO
* @see #MULTIPART_MODE_MIXED
* @see #MULTIPART_MODE_RELATED
* @see #MULTIPART_MODE_MIXED_RELATED
*/
public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode, String encoding)
throws MessagingException {
this.mimeMessage = mimeMessage;
createMimeMultiparts(mimeMessage, multipartMode);
this.encoding = (encoding != null ? encoding : getDefaultEncoding(mimeMessage));
this.fileTypeMap = getDefaultFileTypeMap(mimeMessage);
}
/**
* Return the underlying MimeMessage object.
*/
public final MimeMessage getMimeMessage() {
return mimeMessage;
}
/**
* Determine the MimeMultipart objects to use, which will be used
* to store attachments on the one hand and text(s) and inline elements
* on the other hand.
* <p>Texts and inline elements can either be stored in the root element
* itself (MULTIPART_MODE_MIXED, MULTIPART_MODE_RELATED) or in a nested element
* rather than the root element directly (MULTIPART_MODE_MIXED_RELATED).
* <p>By default, the root MimeMultipart element will be of type "mixed"
* (MULTIPART_MODE_MIXED) or "related" (MULTIPART_MODE_RELATED).
* The main multipart element will either be added as nested element of
* type "related" (MULTIPART_MODE_MIXED_RELATED) or be identical to the root
* element itself (MULTIPART_MODE_MIXED, MULTIPART_MODE_RELATED).
* @param mimeMessage the MimeMessage object to add the root MimeMultipart
* object to
* @param multipartMode the multipart mode, as passed into the constructor
* (MIXED, RELATED, MIXED_RELATED, or NO)
* @throws MessagingException if multipart creation failed
* @see #setMimeMultiparts
* @see #MULTIPART_MODE_NO
* @see #MULTIPART_MODE_MIXED
* @see #MULTIPART_MODE_RELATED
* @see #MULTIPART_MODE_MIXED_RELATED
*/
protected void createMimeMultiparts(MimeMessage mimeMessage, int multipartMode) throws MessagingException {
switch (multipartMode) {
case MULTIPART_MODE_NO:
setMimeMultiparts(null, null);
break;
case MULTIPART_MODE_MIXED:
MimeMultipart mixedMultipart = new MimeMultipart(MULTIPART_SUBTYPE_MIXED);
mimeMessage.setContent(mixedMultipart);
setMimeMultiparts(mixedMultipart, mixedMultipart);
break;
case MULTIPART_MODE_RELATED:
MimeMultipart relatedMultipart = new MimeMultipart(MULTIPART_SUBTYPE_RELATED);
mimeMessage.setContent(relatedMultipart);
setMimeMultiparts(relatedMultipart, relatedMultipart);
break;
case MULTIPART_MODE_MIXED_RELATED:
MimeMultipart rootMixedMultipart = new MimeMultipart(MULTIPART_SUBTYPE_MIXED);
mimeMessage.setContent(rootMixedMultipart);
MimeMultipart nestedRelatedMultipart = new MimeMultipart(MULTIPART_SUBTYPE_RELATED);
MimeBodyPart relatedBodyPart = new MimeBodyPart();
relatedBodyPart.setContent(nestedRelatedMultipart);
rootMixedMultipart.addBodyPart(relatedBodyPart);
setMimeMultiparts(rootMixedMultipart, nestedRelatedMultipart);
break;
default:
throw new IllegalArgumentException("Only multipart modes MIXED_RELATED, RELATED and NO supported");
}
}
/**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -