SpringBoot2.x 实现邮件发送

SpringBoot实现发送邮件

之前遇到了一个基于SpringBoot项目实现发送邮件的功能,所以当时在开发功能之前写了一个基于SpringBoot2.x实现发送邮件的demo,之前在论坛中看有人问SpringBoot应该怎么实现正文是html模板并且带有附件的邮件发送功能。之前写的demo正好符合这个需求,所以在这里把代码进行一下分享。

话不多说直接上代码

1.Application.yml配置
spring: 
	mail:
	    #smtp服务地址
	    host: smtp.qq.com
	    #邮箱账号
	    username: 123456789@qq.com
	    #邮箱密码或者授权码(不同的邮箱不一样QQ邮箱是授权码,但是有的邮箱也可以直接使用密码)
	    password: xxxxxxxxxxxx
	    properties:
	      mail: 
	        smtp: 
	          auth: true
	          starttls: 
	            enable: true
	            required: true
	    default-encoding: UTF-8
2. 邮件发送MailService接口

public interface MailService {

    /**
     * 发送邮件
     * @param entity
     */
    void sendMail(MailEntity entity);

    /**
     * 检验MailEntity是否合法
     * @param entity
     * @return
     */
    boolean checkMailEntity(MailEntity entity);
}
3. 邮件实体MailEntity
import lombok.Builder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamSource;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * 邮件实体
 */
@Slf4j
public class MailEntity {

    /**
     * 收件人
     */
    private Set<String> mialTos = new LinkedHashSet<>();

    /**
     * 邮件密送人
     */
    private Set<String> mailBcc = new LinkedHashSet<>();

    /**
     * 邮件抄送人
     */
    private Set<String> mailCc = new LinkedHashSet<>();

    /**
     * 邮件附件
     */
    private Set<MailAttachment> attachments = new LinkedHashSet<>();

    /**
     * 是否存在附件
     */
    private boolean hasAttachments = false;

    /**
     * 邮件主题
     */
    private String mailSubject;

    /**
     * 邮件内容
     */
    private String mailContent;

    /**
     * html格式邮件
     */
    private boolean html = false;

    /**
     * 邮件发件人
     */
    private String mailFrom;

    /**
     * 得到收件人
     * @return
     */
    public String[] getMialTos() {
        return asArray(this.mialTos);
    }

    /**
     * 设置收件人
     * @param mailTos 收件人邮箱地址
     */
    public void setMailTos(String... mailTos) {
        this.mialTos = asSet(mailTos);
    }

    /**
     * 得到密送人
     * @return
     */
    public String[] getMailBcc() {
        return asArray(this.mailBcc);
    }

    /**
     * 设置密送人
     * @param mailBcc 密送人邮箱地址
     */
    public void setMailBcc(String... mailBcc) {
        this.mailBcc = asSet(mailBcc);
    }

    /**
     * 得到抄送人
     * @return
     */
    public String[] getMailCc() {
        return asArray(this.mailCc);
    }

    /**
     * 设置抄送人
     * @param mailCc 抄送人邮箱地址
     */
    public void setMailCc(String... mailCc) {
        this.mailCc = asSet(mailCc);
    }

    /**
     * 得到邮件主题
     * @return
     */
    public String getMailSubject() {
        return mailSubject;
    }

    /**
     * 设置邮件主题
     * @param mailSubject 邮件主题
     */
    public void setMailSubject(String mailSubject) {
        this.mailSubject = mailSubject;
    }

    /**
     * 得到邮件内容
     * @return
     */
    public String getMailContent() {
        return mailContent;
    }

    /**
     * 设置邮件内容
     * @param mailContent
     */
    public void setMailContent(String mailContent) {
        this.mailContent = mailContent;
    }

    /**
     * 设置邮件正文是否是Html形式
     * @param html
     */
    public void setHtmlContant(boolean html) {
        this.html = html;
    }

    /**
     * 判断邮件正文是否是Html形式
     * @return
     */
    public boolean isHtmlContant() {
        return this.html;
    }

    /**
     * 得到邮件附件集合
     * @return
     */
    public Set<MailAttachment> getAttachments() {
        return attachments;
    }

    /**
     * 判断是否包含附件
     * @return
     */
    public boolean isHasAttachments() {
        return hasAttachments;
    }

    /**
     * 设置发件人
     * @param mailFrom 发件人邮箱地址
     */
    public void setMailFrom(String mailFrom) {
        this.mailFrom = mailFrom;
    }

    /**
     * 得到发件人邮箱地址
     * @return
     */
    public String getMailFrom() {
        return mailFrom;
    }

    /**
     * 将Set<String>转为String[]
     * @param arg Set<String>
     * @return
     */
    private String[] asArray(Set<String> arg){
        return CollectionUtils.isEmpty(arg) ? null : arg.toArray(new String[arg.size()]);
    }

    /**
     * 将String[]转为Set<String>
     * @param arg String[]
     * @return
     */
    private Set<String> asSet(String... arg){
        Set<String> set = new LinkedHashSet<>();
        if(null == arg || arg.length == 0){
            return set;
        }
        set = new LinkedHashSet<>(new ArrayList<>(Arrays.asList(arg)));
        return set;
    }

    /**
     * 添加附件
     * @param attachmentName 附件名
     * @param attachment 附件输入流
     */
    public void addAttachment(String attachmentName,InputStream attachment){
        if(StringUtils.isBlank(attachmentName)
                || null == attachment) {
            log.error("无效的资源,参数attachmentName或attachment为空");
            return;
        }
        BufferedInputStream buffer = new BufferedInputStream(attachment);
        byte[] bt = null;
        try {
            bt = new byte[buffer.available()];
            buffer.read(bt);
        } catch (IOException e) {
            log.error("邮件附件读取异常",e);
        } finally {
            try {
                attachment.close();
                buffer.close();
            } catch (IOException e) {
                log.error("InputStream关闭异常",e);
            }
        }
        if(null != bt) {
            addAttachment(attachmentName, bt);
        }
    }

    /**
     * 添加附件
     * @param attachmentName 附件名
     * @param attachment 附件文件对象
     */
    public void addAttachment(String attachmentName, File attachment){
        if(null == attachment || !attachment.exists()){
            log.error("无效的资源,参数attachment为空或不存在");
            return;
        }
        InputStream inputStream = null;
        try {
            inputStream = new FileInputStream(attachment);
            addAttachment(attachmentName,inputStream);
        } catch (FileNotFoundException e) {
           log.error("文件未找到异常",e);
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                log.error("FileInputStream关闭异常",e);
            }
        }
    }


    /**
     * 添加附件
     * @param attachmentName 附件名
     * @param attachmentPath 附件路径
     */
    public void addAttachment(String attachmentName,String attachmentPath){
        if(StringUtils.isBlank(attachmentPath)){
            log.error("无效的资源,参数attachmentPath为空");
            return;
        }
        File attachment = new File(attachmentPath);
        addAttachment(attachmentName,attachment);
    }

    /**
     * 添加附件
     * @param attachmentName 附件名
     * @param attachmentByteArray 附件字节数组
     */
    public void addAttachment(String attachmentName,byte[] attachmentByteArray){
        if(null == attachmentByteArray || attachmentByteArray.length == 0){
            log.error("无效的资源,参数attachmentByteArray为空");
        }
        this.attachments.add(MailAttachment.builder()
                .attachmentName(attachmentName)
                .attachment(new ByteArrayResource(attachmentByteArray)).build());
        this.hasAttachments = true;
    }

    /**
     * 邮件附件实体
     */
    @Builder
    @Getter
    public static final class MailAttachment {
        private String attachmentName;

        private InputStreamSource attachment;
    }

}
4. 邮件发送接口MailService实现类MailServiceImpl
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Set;

@Service
@Slf4j
public class MailServiceImpl implements MailService {

    @Autowired
    private JavaMailSender mailSender;

    @Autowired
    private Environment environment;

    @Override
    public void sendMail(MailEntity entity) {
        if(!checkMailEntity(entity)){
            log.info("entity不合法,邮件发送失败");
        }
        MimeMessage mimeMessage = createNewMimeMessage(entity);
        mailSender.send(mimeMessage);

    }

    @Override
    public boolean checkMailEntity(MailEntity entity) {
        if(null == entity){
            log.info("参数MailEntity为空");
            return false;
        } else if(isEmpty(entity.getMialTos())){
            log.info("收件人为空");
            return false;
        } else if(StringUtils.isBlank(entity.getMailSubject())){
            log.info("邮件主题为空");
            return false;
        }
        return true;
    }

    /**
     * 创建邮件消息对象{@link MimeMessage}
     * @param entity
     * @return
     */
    private MimeMessage createNewMimeMessage(MailEntity entity){
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        final MimeMessageHelper[] helper = new MimeMessageHelper[1];
        try {
            //发件人为空默认读取Application.yml中配置的邮箱
            if(StringUtils.isBlank(entity.getMailFrom())){
                entity.setMailFrom(environment.getProperty("spring.mail.username"));
            }
            //判断邮件是否包含附件
            if(entity.isHasAttachments()){
                //如果邮件包含附件需要使用带有 boolean multipart 参数的构造函数并且指定为true
                helper[0] = new MimeMessageHelper(mimeMessage,true);
            } else {
                helper[0] = new MimeMessageHelper(mimeMessage);
            }
            //设置邮件的收件人
            helper[0].setTo(entity.getMialTos());
            //设置抄送人
            if(null != entity.getMailCc()){
                helper[0].setCc(entity.getMailCc());
            }
            //设置密送人
            if(null != entity.getMailBcc()){
                helper[0].setBcc(entity.getMailBcc());
            }
            //设置邮件主题
            helper[0].setSubject(entity.getMailSubject());
            //邮件正文是否是html格式
            if(entity.isHtmlContant()){
                helper[0].setText(entity.getMailContent(),true);
            } else{
                helper[0].setText(entity.getMailContent(),false);
            }
            //设置发件人
            helper[0].setFrom(entity.getMailFrom());
            //设置附件
            if(entity.isHasAttachments()) {
                Set<MailEntity.MailAttachment> attachments = entity.getAttachments();
                attachments.forEach((attachment) -> {
                    try {
                        helper[0].addAttachment(attachment.getAttachmentName(),attachment.getAttachment());
                    } catch (MessagingException e) {
                       log.error("设置邮件附件异常",e);
                    }
                });
            }
        } catch (MessagingException e) {
            log.error("发送邮件异常",e);
        }
        return mimeMessage;
    }

    /**
     * 判断数组是否为空
     * @param arr
     * @param <T>
     * @return
     */
    private <T> boolean isEmpty(T[] arr){
        if(null == arr || arr.length == 0){
            return true;
        }
        return false;
    }

}
5.测试代码
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.event.annotation.BeforeTestMethod;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

@SpringBootTest
class SpringbootApplicationTests {

	@Autowired
	protected WebApplicationContext webApplicationContext;

	@Autowired
	private MailService mailService;

	protected MockMvc mockMvc;

	@BeforeTestMethod
	public void init() {
		mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
	}

	@Test
	void testSendMail(){
		MailEntity mailEntity = new MailEntity();
		mailEntity.setMailTos("12345678@qq.com");
		mailEntity.setMailSubject("xxx test mail"+System.currentTimeMillis());
		mailEntity.setMailContent("<h1 style='color:red'>这是一个测试邮件</h1>");
		mailEntity.setHtmlContant(true);
		mailEntity.addAttachment("001.jpg","C:\\Users\\92346\\Desktop\\6d468373gw1eqhb4zxjtej21hc0u0tsu.jpg");
		mailService.sendMail(mailEntity);
	}

}
6.测试结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值