JavaMail是提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。正常我们会用JavaMail相关api来写发送邮件的相关代码。
使用过Spring的众多开发者都知道Spring提供了非常好用的 JavaMailSender
接口实现邮件发送。在Spring Boot
的Starter
模块中也为此提供了自动化配置。
SpringBoot集成邮件引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
底层是使用MailMessage
接口
public interface MailMessage {
void setFrom(String var1) throws MailParseException;
void setReplyTo(String var1) throws MailParseException;
void setTo(String var1) throws MailParseException;
void setTo(String... var1) throws MailParseException;
void setCc(String var1) throws MailParseException;
void setCc(String... var1) throws MailParseException;
void setBcc(String var1) throws MailParseException;
void setBcc(String... var1) throws MailParseException;
void setSentDate(Date var1) throws MailParseException;
void setSubject(String var1) throws MailParseException;
void setText(String var1) throws MailParseException;
}
MailMessage有两个实现类,分别是SimpleMailMessage
和MimeMailMessage
SimpleMailMessage
源码
public class SimpleMailMessage implements MailMessage, Serializable {
@Nullable
private String from;
@Nullable
private String replyTo;
@Nullable
private String[] to;
@Nullable
private String[] cc;
@Nullable
private String[] bcc;
@Nullable
private Date sentDate;
@Nullable
private String subject;
@Nullable
private String text;
public SimpleMailMessage() {
}
public SimpleMailMessage(SimpleMailMessage original) {
Assert.notNull(original, "'original' message argument must not be null");
this.from = original.getFrom();
this.replyTo = original.getReplyTo();
this.to = copyOrNull(original.getTo());
this.cc = copyOrNull(original.getCc());
this.bcc = copyOrNull(original.getBcc());
this.sentDate = original.getSentDate();
this.subject = original.getSubject();
this.text = original.getText();
}
public void setFrom(String from) {
this.from = from;
}
@Nullable
public String getFrom() {
return this.from;
}
public void setReplyTo(String replyTo) {
this.replyTo = replyTo;
}
@Nullable
public String getReplyTo() {
return this.replyTo;
}
public void setTo(String to) {
this.to = new String[]{to};
}
public void setTo(String... to) {
this.to = to;
}
@Nullable
public String[] getTo() {
return this.to;
}
public void setCc(String cc) {
this.cc = new String[]{cc};
}
public void setCc(String... cc) {
this.cc = cc;
}
@Nullable
public String[] getCc() {
return this.cc;
}
public void setBcc(String bcc) {
this.bcc = new String[]{bcc};
}
public void setBcc(String... bcc) {
this.bcc = bcc;
}
@Nullable
public String[] getBcc() {
return this.bcc;
}
public void setSentDate(Date sentDate) {
this.sentDate = sentDate;
}
@Nullable
public Date getSentDate() {
return this.sentDate;
}
public void setSubject(String subject) {
this.subject = subject;
}
@Nullable
public String getSubject() {
return this.subject;
}
public void setText(String text) {
this.text = text;
}
@Nullable
public String getText() {
return this.text;
}
public void copyTo(MailMessage target) {
Assert.notNull(target, "'target' MailMessage must not be null");
if (this.getFrom() != null) {
target.setFrom(this.getFrom());
}
if (this.getReplyTo() != null) {
target.setReplyTo(this.getReplyTo());
}
if (this.getTo() != null) {
target.setTo(copy(this.getTo()));
}
if (this.getCc() != null) {
target.setCc(copy(this.getCc()));
}
if (this.getBcc() != null) {
target.setBcc(copy(this.getBcc()));
}
if (this.getSentDate() != null) {
target.setSentDate(this.getSentDate());
}
if (this.getSubject() != null) {
target.setSubject(this.getSubject());
}
if (this.getText() != null) {
target.setText(this.getText());
}
}
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (!(other instanceof SimpleMailMessage)) {
return false;
} else {
SimpleMailMessage otherMessage = (SimpleMailMessage)other;
return ObjectUtils.nullSafeEquals(this.from, otherMessage.from) && ObjectUtils.nullSafeEquals(this.replyTo, otherMessage.replyTo) && ObjectUtils.nullSafeEquals(this.to, otherMessage.to) && ObjectUtils.nullSafeEquals(this.cc, otherMessage.cc) && ObjectUtils.nullSafeEquals(this.bcc, otherMessage.bcc) && ObjectUtils.nullSafeEquals(this.sentDate, otherMessage.sentDate) && ObjectUtils.nullSafeEquals(this.subject, otherMessage.subject) && ObjectUtils.nullSafeEquals(this.text, otherMessage.text);
}
}
public int hashCode() {
int hashCode = ObjectUtils.nullSafeHashCode(this.from);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.replyTo);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.to);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.cc);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.bcc);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.sentDate);
hashCode = 29 * hashCode + ObjectUtils.nullSafeHashCode(this.subject);
return hashCode;
}
public String toString() {
StringBuilder sb = new StringBuilder("SimpleMailMessage: ");
sb.append("from=").append(this.from).append("; ");
sb.append("replyTo=").append(this.replyTo).append("; ");
sb.append("to=").append(StringUtils.arrayToCommaDelimitedString(this.to)).append("; ");
sb.append("cc=").append(StringUtils.arrayToCommaDelimitedString(this.cc)).append("; ");
sb.append("bcc=").append(StringUtils.arrayToCommaDelimitedString(this.bcc)).append("; ");
sb.append("sentDate=").append(this.sentDate).append("; ");
sb.append("subject=").append(this.subject).append("; ");
sb.append("text=").append(this.text);
return sb.toString();
}
@Nullable
private static String[] copyOrNull(@Nullable String[] state) {
return state == null ? null : copy(state);
}
private static String[] copy(String[] state) {
String[] copy = new String[state.length];
System.arraycopy(state, 0, copy, 0, state.length);
return copy;
}
}
MimeMailMessage
源码
public class MimeMailMessage implements MailMessage {
private final MimeMessageHelper helper;
public MimeMailMessage(MimeMessageHelper mimeMessageHelper) {
this.helper = mimeMessageHelper;
}
public MimeMailMessage(MimeMessage mimeMessage) {
this.helper = new MimeMessageHelper(mimeMessage);
}
public final MimeMessageHelper getMimeMessageHelper() {
return this.helper;
}
public final MimeMessage getMimeMessage() {
return this.helper.getMimeMessage();
}
public void setFrom(String from) throws MailParseException {
try {
this.helper.setFrom(from);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setReplyTo(String replyTo) throws MailParseException {
try {
this.helper.setReplyTo(replyTo);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setTo(String to) throws MailParseException {
try {
this.helper.setTo(to);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setTo(String... to) throws MailParseException {
try {
this.helper.setTo(to);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setCc(String cc) throws MailParseException {
try {
this.helper.setCc(cc);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setCc(String... cc) throws MailParseException {
try {
this.helper.setCc(cc);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setBcc(String bcc) throws MailParseException {
try {
this.helper.setBcc(bcc);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setBcc(String... bcc) throws MailParseException {
try {
this.helper.setBcc(bcc);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setSentDate(Date sentDate) throws MailParseException {
try {
this.helper.setSentDate(sentDate);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setSubject(String subject) throws MailParseException {
try {
this.helper.setSubject(subject);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
public void setText(String text) throws MailParseException {
try {
this.helper.setText(text);
} catch (MessagingException var3) {
throw new MailParseException(var3);
}
}
}
参数说明:
subject :邮件主题
content :邮件主题内容
from:发件人Email地址
to:收件人Email地址
MimeMessageHelper
是处理JavaMail
比较顺手的组件之一,可以让你摆脱繁复的JavaMail API
可用于发送附件和嵌入式资源(inline resources),允许添加附件和内嵌资源(inline resources)。
内嵌资源可能是你在信件中希望使用的图像或样式表,但是又不想把它们作为附件。
public class MimeMessageHelper {
public static final int MULTIPART_MODE_NO = 0;
public static final int MULTIPART_MODE_MIXED = 1;
public static final int MULTIPART_MODE_RELATED = 2;
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_PRIORITY = "X-Priority";
private static final String HEADER_CONTENT_ID = "Content-ID";
private final MimeMessage mimeMessage;
@Nullable
private MimeMultipart rootMimeMultipart;
@Nullable
private MimeMultipart mimeMultipart;
@Nullable
private final String encoding;
private FileTypeMap fileTypeMap;
private boolean validateAddresses;
public MimeMessageHelper(MimeMessage mimeMessage) {
this(mimeMessage, (String)null);
}
public MimeMessageHelper(MimeMessage mimeMessage, @Nullable String encoding) {
this.validateAddresses = false;
this.mimeMessage = mimeMessage;
this.encoding = encoding != null ? encoding : this.getDefaultEncoding(mimeMessage);
this.fileTypeMap = this.getDefaultFileTypeMap(mimeMessage);
}
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart) throws MessagingException {
this(mimeMessage, multipart, (String)null);
}
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, @Nullable String encoding) throws MessagingException {
this(mimeMessage, multipart ? 3 : 0, encoding);
}
public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode) throws MessagingException {
this(mimeMessage, multipartMode, (String)null);
}
public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode, @Nullable String encoding) throws MessagingException {
this.validateAddresses = false;
this.mimeMessage = mimeMessage;
this.createMimeMultiparts(mimeMessage, multipartMode);
this.encoding = encoding != null ? encoding : this.getDefaultEncoding(mimeMessage);
this.fileTypeMap = this.getDefaultFileTypeMap(mimeMessage);
}
public final MimeMessage getMimeMessage() {
return this.mimeMessage;
}
protected void createMimeMultiparts(MimeMessage mimeMessage, int multipartMode) throws MessagingException {
switch(multipartMode) {
case 0:
this.setMimeMultiparts((MimeMultipart)null, (MimeMultipart)null);
break;
case 1:
MimeMultipart mixedMultipart = new MimeMultipart("mixed");
mimeMessage.setContent(mixedMultipart);
this.setMimeMultiparts(mixedMultipart, mixedMultipart);
break;
case 2:
MimeMultipart relatedMultipart = new MimeMultipart("related");
mimeMessage.setContent(relatedMultipart);
this.setMimeMultiparts(relatedMultipart, relatedMultipart);
break;
case 3:
MimeMultipart rootMixedMultipart = new MimeMultipart("mixed");
mimeMessage.setContent(rootMixedMultipart);
MimeMultipart nestedRelatedMultipart = new MimeMultipart("related");
MimeBodyPart relatedBodyPart = new MimeBodyPart();
relatedBodyPart.setContent(nestedRelatedMultipart);
rootMixedMultipart.addBodyPart(relatedBodyPart);
this.setMimeMultiparts(rootMixedMultipart, nestedRelatedMultipart);
break;
default:
throw new IllegalArgumentException("Only multipart modes MIXED_RELATED, RELATED and NO supported");
}
}
protected final void setMimeMultiparts(@Nullable MimeMultipart root, @Nullable MimeMultipart main) {
this.rootMimeMultipart = root;
this.mimeMultipart = main;
}
public final boolean isMultipart() {
return this.rootMimeMultipart != null;
}
public final MimeMultipart getRootMimeMultipart() throws IllegalStateException {
if (this.rootMimeMultipart == null) {
throw new IllegalStateException("Not in multipart mode - create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag if you need to set alternative texts or add inline elements or attachments.");
} else {
return this.rootMimeMultipart;
}
}
public final MimeMultipart getMimeMultipart() throws IllegalStateException {
if (this.mimeMultipart == null) {
throw new IllegalStateException("Not in multipart mode - create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag if you need to set alternative texts or add inline elements or attachments.");
} else {
return this.mimeMultipart;
}
}
@Nullable
protected String getDefaultEncoding(MimeMessage mimeMessage) {
return mimeMessage instanceof SmartMimeMessage ? ((SmartMimeMessage)mimeMessage).getDefaultEncoding() : null;
}
@Nullable
public String getEncoding() {
return this.encoding;
}
protected FileTypeMap getDefaultFileTypeMap(MimeMessage mimeMessage) {
if (mimeMessage instanceof SmartMimeMessage) {
FileTypeMap fileTypeMap = ((SmartMimeMessage)mimeMessage).getDefaultFileTypeMap();
if (fileTypeMap != null) {
return fileTypeMap;
}
}
ConfigurableMimeFileTypeMap fileTypeMap = new ConfigurableMimeFileTypeMap();
fileTypeMap.afterPropertiesSet();
return fileTypeMap;
}
public void setFileTypeMap(@Nullable FileTypeMap fileTypeMap) {
this.fileTypeMap = fileTypeMap != null ? fileTypeMap : this.getDefaultFileTypeMap(this.getMimeMessage());
}
public FileTypeMap getFileTypeMap() {
return this.fileTypeMap;
}
public void setValidateAddresses(boolean validateAddresses) {
this.validateAddresses = validateAddresses;
}
public boolean isValidateAddresses() {
return this.validateAddresses;
}
protected void validateAddress(InternetAddress address) throws AddressException {
if (this.isValidateAddresses()) {
address.validate();
}
}
protected void validateAddresses(InternetAddress[] addresses) throws AddressException {
InternetAddress[] var2 = addresses;
int var3 = addresses.length;
for(int var4 = 0; var4 < var3; ++var4) {
InternetAddress address = var2[var4];
this.validateAddress(address);
}
}
public void setFrom(InternetAddress from) throws MessagingException {
Assert.notNull(from, "From address must not be null");
this.validateAddress(from);
this.mimeMessage.setFrom(from);
}
public void setFrom(String from) throws MessagingException {
Assert.notNull(from, "From address must not be null");
this.setFrom(this.parseAddress(from));
}
public void setFrom(String from, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(from, "From address must not be null");
this.setFrom(this.getEncoding() != null ? new InternetAddress(from, personal, this.getEncoding()) : new InternetAddress(from, personal));
}
public void setReplyTo(InternetAddress replyTo) throws MessagingException {
Assert.notNull(replyTo, "Reply-to address must not be null");
this.validateAddress(replyTo);
this.mimeMessage.setReplyTo(new InternetAddress[]{replyTo});
}
public void setReplyTo(String replyTo) throws MessagingException {
Assert.notNull(replyTo, "Reply-to address must not be null");
this.setReplyTo(this.parseAddress(replyTo));
}
public void setReplyTo(String replyTo, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(replyTo, "Reply-to address must not be null");
InternetAddress replyToAddress = this.getEncoding() != null ? new InternetAddress(replyTo, personal, this.getEncoding()) : new InternetAddress(replyTo, personal);
this.setReplyTo(replyToAddress);
}
public void setTo(InternetAddress to) throws MessagingException {
Assert.notNull(to, "To address must not be null");
this.validateAddress(to);
this.mimeMessage.setRecipient(RecipientType.TO, to);
}
public void setTo(InternetAddress[] to) throws MessagingException {
Assert.notNull(to, "To address array must not be null");
this.validateAddresses(to);
this.mimeMessage.setRecipients(RecipientType.TO, to);
}
public void setTo(String to) throws MessagingException {
Assert.notNull(to, "To address must not be null");
this.setTo(this.parseAddress(to));
}
public void setTo(String[] to) throws MessagingException {
Assert.notNull(to, "To address array must not be null");
InternetAddress[] addresses = new InternetAddress[to.length];
for(int i = 0; i < to.length; ++i) {
addresses[i] = this.parseAddress(to[i]);
}
this.setTo(addresses);
}
public void addTo(InternetAddress to) throws MessagingException {
Assert.notNull(to, "To address must not be null");
this.validateAddress(to);
this.mimeMessage.addRecipient(RecipientType.TO, to);
}
public void addTo(String to) throws MessagingException {
Assert.notNull(to, "To address must not be null");
this.addTo(this.parseAddress(to));
}
public void addTo(String to, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(to, "To address must not be null");
this.addTo(this.getEncoding() != null ? new InternetAddress(to, personal, this.getEncoding()) : new InternetAddress(to, personal));
}
public void setCc(InternetAddress cc) throws MessagingException {
Assert.notNull(cc, "Cc address must not be null");
this.validateAddress(cc);
this.mimeMessage.setRecipient(RecipientType.CC, cc);
}
public void setCc(InternetAddress[] cc) throws MessagingException {
Assert.notNull(cc, "Cc address array must not be null");
this.validateAddresses(cc);
this.mimeMessage.setRecipients(RecipientType.CC, cc);
}
public void setCc(String cc) throws MessagingException {
Assert.notNull(cc, "Cc address must not be null");
this.setCc(this.parseAddress(cc));
}
public void setCc(String[] cc) throws MessagingException {
Assert.notNull(cc, "Cc address array must not be null");
InternetAddress[] addresses = new InternetAddress[cc.length];
for(int i = 0; i < cc.length; ++i) {
addresses[i] = this.parseAddress(cc[i]);
}
this.setCc(addresses);
}
public void addCc(InternetAddress cc) throws MessagingException {
Assert.notNull(cc, "Cc address must not be null");
this.validateAddress(cc);
this.mimeMessage.addRecipient(RecipientType.CC, cc);
}
public void addCc(String cc) throws MessagingException {
Assert.notNull(cc, "Cc address must not be null");
this.addCc(this.parseAddress(cc));
}
public void addCc(String cc, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(cc, "Cc address must not be null");
this.addCc(this.getEncoding() != null ? new InternetAddress(cc, personal, this.getEncoding()) : new InternetAddress(cc, personal));
}
public void setBcc(InternetAddress bcc) throws MessagingException {
Assert.notNull(bcc, "Bcc address must not be null");
this.validateAddress(bcc);
this.mimeMessage.setRecipient(RecipientType.BCC, bcc);
}
public void setBcc(InternetAddress[] bcc) throws MessagingException {
Assert.notNull(bcc, "Bcc address array must not be null");
this.validateAddresses(bcc);
this.mimeMessage.setRecipients(RecipientType.BCC, bcc);
}
public void setBcc(String bcc) throws MessagingException {
Assert.notNull(bcc, "Bcc address must not be null");
this.setBcc(this.parseAddress(bcc));
}
public void setBcc(String[] bcc) throws MessagingException {
Assert.notNull(bcc, "Bcc address array must not be null");
InternetAddress[] addresses = new InternetAddress[bcc.length];
for(int i = 0; i < bcc.length; ++i) {
addresses[i] = this.parseAddress(bcc[i]);
}
this.setBcc(addresses);
}
public void addBcc(InternetAddress bcc) throws MessagingException {
Assert.notNull(bcc, "Bcc address must not be null");
this.validateAddress(bcc);
this.mimeMessage.addRecipient(RecipientType.BCC, bcc);
}
public void addBcc(String bcc) throws MessagingException {
Assert.notNull(bcc, "Bcc address must not be null");
this.addBcc(this.parseAddress(bcc));
}
public void addBcc(String bcc, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(bcc, "Bcc address must not be null");
this.addBcc(this.getEncoding() != null ? new InternetAddress(bcc, personal, this.getEncoding()) : new InternetAddress(bcc, personal));
}
private InternetAddress parseAddress(String address) throws MessagingException {
InternetAddress[] parsed = InternetAddress.parse(address);
if (parsed.length != 1) {
throw new AddressException("Illegal address", address);
} else {
InternetAddress raw = parsed[0];
try {
return this.getEncoding() != null ? new InternetAddress(raw.getAddress(), raw.getPersonal(), this.getEncoding()) : raw;
} catch (UnsupportedEncodingException var5) {
throw new MessagingException("Failed to parse embedded personal name to correct encoding", var5);
}
}
}
public void setPriority(int priority) throws MessagingException {
this.mimeMessage.setHeader("X-Priority", Integer.toString(priority));
}
public void setSentDate(Date sentDate) throws MessagingException {
Assert.notNull(sentDate, "Sent date must not be null");
this.mimeMessage.setSentDate(sentDate);
}
public void setSubject(String subject) throws MessagingException {
Assert.notNull(subject, "Subject must not be null");
if (this.getEncoding() != null) {
this.mimeMessage.setSubject(subject, this.getEncoding());
} else {
this.mimeMessage.setSubject(subject);
}
}
public void setText(String text) throws MessagingException {
this.setText(text, false);
}
public void setText(String text, boolean html) throws MessagingException {
Assert.notNull(text, "Text must not be null");
Object partToUse;
if (this.isMultipart()) {
partToUse = this.getMainPart();
} else {
partToUse = this.mimeMessage;
}
if (html) {
this.setHtmlTextToMimePart((MimePart)partToUse, text);
} else {
this.setPlainTextToMimePart((MimePart)partToUse, text);
}
}
public void setText(String plainText, String htmlText) throws MessagingException {
Assert.notNull(plainText, "Plain text must not be null");
Assert.notNull(htmlText, "HTML text must not be null");
MimeMultipart messageBody = new MimeMultipart("alternative");
this.getMainPart().setContent(messageBody, "text/alternative");
MimeBodyPart plainTextPart = new MimeBodyPart();
this.setPlainTextToMimePart(plainTextPart, plainText);
messageBody.addBodyPart(plainTextPart);
MimeBodyPart htmlTextPart = new MimeBodyPart();
this.setHtmlTextToMimePart(htmlTextPart, htmlText);
messageBody.addBodyPart(htmlTextPart);
}
private MimeBodyPart getMainPart() throws MessagingException {
MimeMultipart mimeMultipart = this.getMimeMultipart();
MimeBodyPart bodyPart = null;
for(int i = 0; i < mimeMultipart.getCount(); ++i) {
BodyPart bp = mimeMultipart.getBodyPart(i);
if (bp.getFileName() == null) {
bodyPart = (MimeBodyPart)bp;
}
}
if (bodyPart == null) {
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeMultipart.addBodyPart(mimeBodyPart);
bodyPart = mimeBodyPart;
}
return bodyPart;
}
private void setPlainTextToMimePart(MimePart mimePart, String text) throws MessagingException {
if (this.getEncoding() != null) {
mimePart.setText(text, this.getEncoding());
} else {
mimePart.setText(text);
}
}
private void setHtmlTextToMimePart(MimePart mimePart, String text) throws MessagingException {
if (this.getEncoding() != null) {
mimePart.setContent(text, "text/html;charset=" + this.getEncoding());
} else {
mimePart.setContent(text, "text/html");
}
}
public void addInline(String contentId, DataSource dataSource) throws MessagingException {
Assert.notNull(contentId, "Content ID must not be null");
Assert.notNull(dataSource, "DataSource must not be null");
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDisposition("inline");
mimeBodyPart.setHeader("Content-ID", "<" + contentId + ">");
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
this.getMimeMultipart().addBodyPart(mimeBodyPart);
}
public void addInline(String contentId, File file) throws MessagingException {
Assert.notNull(file, "File must not be null");
FileDataSource dataSource = new FileDataSource(file);
dataSource.setFileTypeMap(this.getFileTypeMap());
this.addInline(contentId, (DataSource)dataSource);
}
public void addInline(String contentId, Resource resource) throws MessagingException {
Assert.notNull(resource, "Resource must not be null");
String contentType = this.getFileTypeMap().getContentType(resource.getFilename());
this.addInline(contentId, resource, contentType);
}
public void addInline(String contentId, InputStreamSource inputStreamSource, String contentType) throws MessagingException {
Assert.notNull(inputStreamSource, "InputStreamSource must not be null");
if (inputStreamSource instanceof Resource && ((Resource)inputStreamSource).isOpen()) {
throw new IllegalArgumentException("Passed-in Resource contains an open stream: invalid argument. JavaMail requires an InputStreamSource that creates a fresh stream for every call.");
} else {
DataSource dataSource = this.createDataSource(inputStreamSource, contentType, "inline");
this.addInline(contentId, dataSource);
}
}
public void addAttachment(String attachmentFilename, DataSource dataSource) throws MessagingException {
Assert.notNull(attachmentFilename, "Attachment filename must not be null");
Assert.notNull(dataSource, "DataSource must not be null");
try {
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setDisposition("attachment");
mimeBodyPart.setFileName(MimeUtility.encodeText(attachmentFilename));
mimeBodyPart.setDataHandler(new DataHandler(dataSource));
this.getRootMimeMultipart().addBodyPart(mimeBodyPart);
} catch (UnsupportedEncodingException var4) {
throw new MessagingException("Failed to encode attachment filename", var4);
}
}
public void addAttachment(String attachmentFilename, File file) throws MessagingException {
Assert.notNull(file, "File must not be null");
FileDataSource dataSource = new FileDataSource(file);
dataSource.setFileTypeMap(this.getFileTypeMap());
this.addAttachment(attachmentFilename, (DataSource)dataSource);
}
public void addAttachment(String attachmentFilename, InputStreamSource inputStreamSource) throws MessagingException {
String contentType = this.getFileTypeMap().getContentType(attachmentFilename);
this.addAttachment(attachmentFilename, inputStreamSource, contentType);
}
public void addAttachment(String attachmentFilename, InputStreamSource inputStreamSource, String contentType) throws MessagingException {
Assert.notNull(inputStreamSource, "InputStreamSource must not be null");
if (inputStreamSource instanceof Resource && ((Resource)inputStreamSource).isOpen()) {
throw new IllegalArgumentException("Passed-in Resource contains an open stream: invalid argument. JavaMail requires an InputStreamSource that creates a fresh stream for every call.");
} else {
DataSource dataSource = this.createDataSource(inputStreamSource, contentType, attachmentFilename);
this.addAttachment(attachmentFilename, dataSource);
}
}
protected DataSource createDataSource(final InputStreamSource inputStreamSource, final String contentType, final String name) {
return new DataSource() {
public InputStream getInputStream() throws IOException {
return inputStreamSource.getInputStream();
}
public OutputStream getOutputStream() {
throw new UnsupportedOperationException("Read-only javax.activation.DataSource");
}
public String getContentType() {
return contentType;
}
public String getName() {
return name;
}
};
}
}
邮件发送接口主要使用JavaMailSender
JavaMailSender
接口源码
public interface JavaMailSender extends MailSender {
MimeMessage createMimeMessage();
MimeMessage createMimeMessage(InputStream var1) throws MailException;
void send(MimeMessage var1) throws MailException;
void send(MimeMessage... var1) throws MailException;
void send(MimeMessagePreparator var1) throws MailException;
void send(MimeMessagePreparator... var1) throws MailException;
}
JavaMailSender
实现类为JavaMailSenderImpl
,主要看邮件发送方法
JavaMailSenderImpl
核心源码
public class JavaMailSenderImpl implements JavaMailSender {
public void send(SimpleMailMessage simpleMessage) throws MailException {
this.send(simpleMessage);
}
public void send(SimpleMailMessage... simpleMessages) throws MailException {
List<MimeMessage> mimeMessages = new ArrayList(simpleMessages.length);
SimpleMailMessage[] var3 = simpleMessages;
int var4 = simpleMessages.length;
for(int var5 = 0; var5 < var4; ++var5) {
SimpleMailMessage simpleMessage = var3[var5];
MimeMailMessage message = new MimeMailMessage(this.createMimeMessage());
simpleMessage.copyTo(message);
mimeMessages.add(message.getMimeMessage());
}
this.doSend((MimeMessage[])mimeMessages.toArray(new MimeMessage[0]), simpleMessages);
}
public void send(MimeMessage mimeMessage) throws MailException {
this.send(mimeMessage);
}
public void send(MimeMessage... mimeMessages) throws MailException {
this.doSend(mimeMessages, (Object[])null);
}
public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException {
this.send(mimeMessagePreparator);
}
public void send(MimeMessagePreparator... mimeMessagePreparators) throws MailException {
try {
List<MimeMessage> mimeMessages = new ArrayList(mimeMessagePreparators.length);
MimeMessagePreparator[] var3 = mimeMessagePreparators;
int var4 = mimeMessagePreparators.length;
for(int var5 = 0; var5 < var4; ++var5) {
MimeMessagePreparator preparator = var3[var5];
MimeMessage mimeMessage = this.createMimeMessage();
preparator.prepare(mimeMessage);
mimeMessages.add(mimeMessage);
}
this.send((MimeMessage[])mimeMessages.toArray(new MimeMessage[0]));
} catch (MailException var8) {
throw var8;
} catch (MessagingException var9) {
throw new MailParseException(var9);
} catch (Exception var10) {
throw new MailPreparationException(var10);
}
}
public MimeMessage createMimeMessage() {
return new SmartMimeMessage(this.getSession(), this.getDefaultEncoding(), this.getDefaultFileTypeMap());
}
public MimeMessage createMimeMessage(InputStream contentStream) throws MailException {
try {
return new MimeMessage(this.getSession(), contentStream);
} catch (Exception var3) {
throw new MailParseException("Could not parse raw MIME content", var3);
}
}
......
}
SpringBoot实现邮件发送
YML配置
spring:
mail:
host: smtp.qq.com
username: 发送者邮箱
password: 邮箱授权码
default-encoding: UTF-8
spring.mail.host
为邮箱服务商的smtp地址
spring.mail.username
:发送者邮箱
spring.mail.password
邮箱服务商授权码
发送方必须要开启smtp,获取到的授权码,QQ邮箱获取授权码方法如下:
https://service.mail.qq.com/cgi-bin/help?subtype=1&&no=1001256&&id=28
使用SimpleMailMessage,设置发件人邮箱,收件人邮箱,主题和正文。
1.普通文本邮件发送
@Service
public class MailService {
@Value("${spring.mail.username}")
private String from;
@Autowired
JavaMailSender javaMailSender;
public void sendSimpleMail(String to,String subject,String content){
SimpleMailMessage simpleMailMessage=new SimpleMailMessage();
simpleMailMessage.setFrom(from);
simpleMailMessage.setTo(to);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(content);
javaMailSender.send(simpleMailMessage);
}
}
单元测试
@Autowired
MailService mailService;
@Test
public void test() throws MessagingException {
mailService.sendSimpleMail("邮箱","主题","测试内容");
}
测试结果
MimeMessages为复杂邮件模板,支持文本、附件、HTML、图片等。
2.发送HTML邮件
创建MimeMessageHelper
对象,处理MimeMessage
的辅助类。
@Service
public class MailService {
@Value("${spring.mail.username}")
private String from;
@Autowired
JavaMailSender javaMailSender;
public void sendHtmlMail(String to,String subject,String content) throws MessagingException {
MimeMessage mimeMessage=javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper=new MimeMessageHelper(mimeMessage,true);
mimeMessageHelper.setFrom(from);
mimeMessageHelper.setTo(to);
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setText(content,true);
javaMailSender.send(mimeMessage);
}
}
这里要注意的是发送HTML
内容时需要设置html
开启,默认为false
public void setText(String text, boolean html) throws MessagingException {
Assert.notNull(text, "Text must not be null");
Object partToUse;
if (this.isMultipart()) {
partToUse = this.getMainPart();
} else {
partToUse = this.mimeMessage;
}
if (html) {
this.setHtmlTextToMimePart((MimePart)partToUse, text);
} else {
this.setPlainTextToMimePart((MimePart)partToUse, text);
}
}
单元测试
@Autowired
MailService mailService;
@Test
public void test() throws MessagingException {
String content="<html>\n"+
"<body>\n"+
"<h3>hello world</h3>\n"+
"</body>\n"+
"</html>";
mailService.sendHtmlMail("邮箱","主题",content);
}
测试结果
3.发送附件邮件
@Service
public class MailService {
@Value("${spring.mail.username}")
private String from;
@Autowired
JavaMailSender javaMailSender;
public void sendAttachmentMail(String to,String subject,String content,String filePath) throws MessagingException {
MimeMessage mimeMessage=javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper=new MimeMessageHelper(mimeMessage,true);
mimeMessageHelper.setFrom(from);
mimeMessageHelper.setTo(to);
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setText(content,true);
FileSystemResource fileSystemResource=new FileSystemResource(new File(filePath));
String fileName=fileSystemResource.getFilename();
mimeMessageHelper.addAttachment(fileName,fileSystemResource);
javaMailSender.send(mimeMessage);
}
}
需要开启邮件附件
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart) throws MessagingException {
this(mimeMessage, multipart, (String)null);
}
addAttachment()
方法是添加附件
public void addAttachment(String attachmentFilename, InputStreamSource inputStreamSource) throws MessagingException {
String contentType = this.getFileTypeMap().getContentType(attachmentFilename);
this.addAttachment(attachmentFilename, inputStreamSource, contentType);
}
单元测试
@Autowired
MailService mailService;
@Test
public void test() throws MessagingException {
mailService.sendAttachmentMail("邮箱","主题","测试内容","E:\\文件名");
}