Java 中 Spring Boot 框架下的 Email 开发

Email 开发

1. 核心依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

hutool工具包:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.11</version>
</dependency>

2. 邮件实体类

  • 这个类更贴近我们的常见信息,用这个去构造邮箱框架的指定邮件类的构造。
@Data
public class EmailMessage implements Serializable {

    private String sender;

    String[] recipient;

    String[] carbonCopy;

    private String title;

    private String content;

    private Date createTime;

    private static final long serialVersionUID = 1L;

    public void setRecipient(String... recipient) {
        this.recipient = recipient;
    }

    public void setCarbonCopy(String... cc) {
        this.carbonCopy = cc;
    }

    public void setRecipient(@NonNull String recipient) {
        this.recipient = new String[]{recipient};
    }

    public void setCarbonCopy(@NonNull String cc) {
        this.carbonCopy = new String[]{cc};
    }

    public String[] getRecipient() {
        return recipient;
    }

    public String[] getCarbonCopy() {
        return carbonCopy;
    }

    public String getRecipient(int i) {
        return recipient != null ? recipient[i] : null;
    }

    public String getCarbonCopy(int i) {
        return carbonCopy != null ? carbonCopy[i] : null;
    }

}

邮箱格式检查:

public class EmailValidator {

    public static final String EMAIL_PATTERN = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
    
    public static boolean isEmailAccessible(String email) {
        return email.matches(EMAIL_PATTERN);
    }

}

3. 配置

spring:
  mail:
    host: # 邮箱服务器地址(不填会无法启动成功)
    port: # 邮箱服务器端口
    username: # 发起者的邮箱地址
    password: # 密码(是调用邮箱接口的授权密码,不是邮箱账户密码)
    default-encoding: utf-8
    properties:
      mail:
        smtp:
          socketFactory:
            class: javax.net.ssl.SSLSocketFactory

以 yeah.net 邮箱为例(其他的邮箱也会有,举一反三)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

根据指导即可,获得授权密码!

以smtp为例:

  • 这个就是host,可以查一下,port是465(其他的服务器 port是啥,一查便知)

在这里插入图片描述

4. 发送邮件(都是可群发的)

@Component
@Slf4j
@RequiredArgsConstructor
public class EmailSender {

    private final JavaMailSender javaMailSender;

    private final TemplateEngine templateEngine;
    
    public SimpleMailMessage emailToSimpleMailMessage(EmailMessage emailMessage) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        simpleMailMessage.setFrom(emailMessage.getSender());
        simpleMailMessage.setTo(emailMessage.getRecipient());
        simpleMailMessage.setCc(emailMessage.getCarbonCopy());
        simpleMailMessage.setSubject(emailMessage.getTitle());
        simpleMailMessage.setText(emailMessage.getContent());
        return simpleMailMessage;
    }

    public MimeMessageHelper emailIntoMimeMessageByHelper(MimeMessage mimeMessage, EmailMessage emailMessage) {
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setFrom(emailMessage.getSender());
            mimeMessageHelper.setCc(emailMessage.getCarbonCopy());
            mimeMessageHelper.setSubject(emailMessage.getTitle());
            mimeMessageHelper.setTo(emailMessage.getRecipient());
            return mimeMessageHelper;
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

4.1 发送普通邮件(纯文本)

public void sendSimpleMailMessage(EmailMessage emailMessage) {
    if (Objects.isNull(emailMessage)) {
        throw new RuntimeException("email不能为null!");
    }
    // 封装simpleMailMessage对象
    SimpleMailMessage simpleMailMessage = emailToSimpleMailMessage(emailMessage);
    // 发送
    javaMailSender.send(simpleMailMessage);
}

4.2 发送邮件待附件

public void sendMailWithFile(EmailMessage emailMessage, File... files) {
    if (Objects.isNull(emailMessage)) {
        throw new RuntimeException("email不能为null!");
    }
    // 封装对象
    try {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = emailIntoMimeMessageByHelper(mimeMessage, emailMessage);
        // 添加附件
        for (File file : files) {
            if (Objects.nonNull(file)) {
                mimeMessageHelper.addAttachment(file.getName(), file);
            }
        }
        mimeMessageHelper.setText(emailMessage.getContent(), false);
        javaMailSender.send(mimeMessage);
    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }
}

4.3 发送模板邮件

public void sendModelMail(EmailMessage emailMessage, String template, Object modelMessage) {
    if (Objects.isNull(emailMessage)) {
        throw new RuntimeException("email不能为null!");
    }
    // 封装对象
    try {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = emailIntoMimeMessageByHelper(mimeMessage, emailMessage);
        // 构造模板消息
        Context context = new Context();
        context.setVariables(BeanUtil.beanToMap(modelMessage));
        //合并模板与数据
        String content = templateEngine.process(template, context);
        mimeMessageHelper.setText(content, true);
        javaMailSender.send(mimeMessage);
    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }
}

其中,template是模板html的路径,以类路径(resources)下的templates包为根目录!

在这里插入图片描述

邮件显示的一些对html语法的兼容问题,可以参考文章:HTML邮件 兼容问题_foxmail对html样式支持不好-CSDN博客

一个模板html例子:

  • 经典的邮箱验证登录
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>邮箱验证</title>
  </head>
  <body>
    <span>
      &nbsp;下面是您的身份验证码:
    </span>
    <br />
    <font style="font-size: 50pt">
      &nbsp;<span th:text="${code}"></span>
    </font>
    <br />
    <span>&nbsp;请在&nbsp;</span>
    <font style="font-size: 20pt; color: brown">
      <span th:text="${minutes}"></span>
    </font>
    <span>&nbsp;分钟内完成验证,如非本人操作,请忽略!</span>
  </body>
</html>

在这里插入图片描述

原理:将传入的Map的键值对,替换到html里

在这里插入图片描述

4.4 发送模板邮件带附件

public void sendModelMailWithFile(EmailMessage emailMessage, String template, Object modelMessage, File... files) {
    if (Objects.isNull(emailMessage)) {
        throw new RuntimeException("email不能为null!");
    }
    // 封装对象
    try {
        MimeMessage mimeMessage = javaMailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = emailIntoMimeMessageByHelper(mimeMessage, emailMessage);
        // 构造模板消息
        Context context = new Context();
        context.setVariables(BeanUtil.beanToMap(modelMessage));
        //合并模板与数据
        String content = templateEngine.process(template, context);
        mimeMessageHelper.setText(content, true);
        // 添加附件
        for (File file : files) {
            if (Objects.nonNull(file)) {
                mimeMessageHelper.addAttachment(file.getName(), file);
            }
        }
        javaMailSender.send(mimeMessage);
    } catch (MessagingException e) {
        throw new RuntimeException(e);
    }
}

4.5 根据收件人自定义发送模板邮件并且带附件

public <T, R> void customizedSendEmail(EmailMessage emailMessage, String template, Function<T, R> function, File... files) {
    if (Objects.isNull(emailMessage)) {
        throw new RuntimeException("email不能为null!");
    }
    String sender = emailMessage.getSender();
    String[] carbonCopy = emailMessage.getCarbonCopy();
    String title = emailMessage.getTitle();
    Arrays.stream(emailMessage.getRecipient())
            .parallel()
            .distinct()
            .forEach(s -> {
                try {
                    // 封装对象
                    MimeMessage mimeMessage = javaMailSender.createMimeMessage();
                    MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
                    mimeMessageHelper.setTo(s);
                    mimeMessageHelper.setFrom(sender);
                    mimeMessageHelper.setCc(carbonCopy);
                    mimeMessageHelper.setSubject(title);
                    // 添加附件
                    for (File file : files) {
                        if (Objects.nonNull(file)) {
                            mimeMessageHelper.addAttachment(file.getName(), file);
                        }
                    }
                    // 构造模板消息
                    Context context = new Context();
                    Object modelMessage = function.apply((T) s);
                    context.setVariables(BeanUtil.beanToMap(modelMessage));
                    //合并模板与数据
                    String content = templateEngine.process(template, context);
                    // 通过mimeMessageHelper设置到mimeMessage里
                    mimeMessageHelper.setText(content, true);
                    //发送
                    javaMailSender.send(mimeMessage);
                } catch (MessagingException e) {
                    throw new RuntimeException(e);
                }
            });
}
  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

s:103

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值