发送邮件应该是网站的必备功能之一,什么注册验证,忘记密码或者是给用户发送营销信息,本文将采用两种方式发送邮件。

使用javax.mail发送邮件

pom.xm引入依赖

<dependency>
  <groupId>javax.mail</groupId>
  <artifactId>mail</artifactId>
  <version>1.4.7</version>
</dependency>

编写工具类 EmailUtil.java

@Component
public class EmailUtil {
    /**
     * 进行base64加密,防止中文乱码
     */
    private static String changeEncode(String str) {
        try {
            str = MimeUtility.encodeText(new String(str.getBytes(), StandardCharsets.UTF_8), "UTF-8", "B"); // "B"代表Base64
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 发送邮件
     *
     * @param emailInfo 邮件信息
     * @return Success: true; Error: false
     */
    public boolean sendHtmlMail(EmailInfo emailInfo) {
        Properties properties = new Properties();
        properties.put("mail.smtp.host", emailInfo.getSmtpServer());
        properties.put("mail.transport.protocol", "smtp");
        properties.put("mail.smtp.auth", "true");
        properties.put("mail.smtp.socketFactory.class", emailInfo.getSSL_FACTORY()); // 使用JSSE的SSL
        properties.put("mail.smtp.socketFactory.fallback", "false"); // 只处理SSL的连接,对于非SSL的连接不做处理
        properties.put("mail.smtp.port", emailInfo.getPort());
        properties.put("mail.smtp.socketFactory.port", emailInfo.getPort());
        Session session = Session.getInstance(properties);
        session.setDebug(true);
        MimeMessage message = new MimeMessage(session);

        try {
            // 发件人
            Address address = new InternetAddress(emailInfo.getFromUserName());
            message.setFrom(address);
            // 收件人
            Address toAddress = new InternetAddress(emailInfo.getToUser());
            message.setRecipient(MimeMessage.RecipientType.TO, toAddress); // 设置收件人,并设置其接收类型为TO

            // 主题message.setSubject(changeEncode(emailInfo.getSubject()));
            message.setSubject(emailInfo.getSubject());
            // 时间
            message.setSentDate(new Date());

            Multipart multipart = new MimeMultipart();

            // 创建一个包含HTML内容的MimeBodyPart
            BodyPart html = new MimeBodyPart();
            // 设置HTML内容
            html.setContent(emailInfo.getContent(), "text/html; charset=utf-8");
            multipart.addBodyPart(html);
            // 将MiniMultipart对象设置为邮件内容
            message.setContent(multipart);
            message.saveChanges();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        try {
            Transport transport = session.getTransport("smtp");
            transport.connect(emailInfo.getSmtpServer(), emailInfo.getFromUserName(), emailInfo.getFromUserPassword());
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }
}

其中,封装好的 EmailInfo.java 如下

@Data
public class EmailInfo {
    private final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
    private String smtpServer; // SMTP服务器地址
    private String port; // 端口
    private String fromUserName; // 登录SMTP服务器的用户名,发送人邮箱地址
    private String fromUserPassword; // 登录SMTP服务器的密码
    private String toUser; // 收件人
    private String subject; // 邮件主题
    private String content; // 邮件正文

    public EmailInfo(String toUser, String subject, String content) {
        this.toUser = toUser;
        this.subject = subject;
        this.content = content;
        this.smtpServer = "smtp.mxhichina.com";
        this.port = "465";
        this.fromUserName = "UserName";
this.fromUserPassword = "Password";
} }

这里我使用的是本人的域名邮箱 1@wuguangnuo.cn 做发送邮件测试:

编写测试类:

public String sendMail(String eMail) {
    if (Strings.isNullOrEmpty(eMail)) return "eMail 不能为空!";
    if (!eMail.matches("[\\w.\\-]+@([\\w\\-]+\\.)+[\\w\\-]+")) return "邮箱地址格式错误!";

    String subject = "测试邮件 from SpringBoot API";
String content = "<div style='font-size:16px;user-select:none'><p>这是一封<strong style='color:red;font-size:20px;'>测试邮件</strong>。</p><p>点击进入\uD83D\uDC49<a style='color:blue;text-decoration:none'href='http://www.wuguangnuo.cn/blog'>諾的博客|諾wugn-造轮子ing</a></p><p style='font-size:14px;font-family:Courier New'>@author <a style='color:black;text-decoration:none'href='https://github.com/wuguangnuo'>WuGuangNuo</a></p></div>"; EmailInfo emailInfo = new EmailInfo(eMail, subject, content); return emailUtil.sendHtmlMail(emailInfo) ? "发送成功!" : "发送失败";}

发送邮件结果如下:




使用 spring-boot-starter-mail 发送邮件

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

application.yml 配置:

spring:
  mail:
    host: smtp.mxhichina.com //邮箱服务器地址
    username: 1@wuguangnuo.cn //用户名
    password: password    //密码
    default-encoding: UTF-8

发送邮件实现类 MailServiceImpl.java :

@Slf4j
@Component
public class MailServiceImpl implements MailService{
  
  @Autowired
  private JavaMailSender mailSender;
  
  @Override
  public void sendSimpleMail(String to, String subject, String content) {
    SimpleMailMessage message = new SimpleMailMessage();
    message.setFrom("1@wuguangnuo.cn");
    message.setTo(to);
    message.setSubject(subject);
    message.setText(content);

    try {
      mailSender.send(message);
      logger.info("邮件发送成功。");
    } catch (Exception e) {
      logger.error("邮件发送异常!", e);
    }

  }
}

编写测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest {

  @Autowired
  private MailService MailService;

  @Test
  public void testSimpleMail() throws Exception {
    MailService.sendSimpleMail("wuguangnuo@qq.com", "测试邮件", "hello! this is simple mail.");
  }
}

一个简单的文本发送就完成了。 

发送 html 格式邮件:其它都不变在 MailService 添加 sendHtmlMail 方法

public void sendHtmlMail(String to, String subject, String content) {
  MimeMessage message = mailSender.createMimeMessage();

  try {
    // true表示需要创建一个multipart message
    MimeMessageHelper helper = new MimeMessageHelper(message, true);
    helper.setFrom(from);
    helper.setTo(to);
    helper.setSubject(subject);
    helper.setText(content, true);

    mailSender.send(message);
    logger.info("html邮件发送成功");
  } catch (MessagingException e) {
    logger.error("html邮件发送异常!", e);
  }
}

在测试类中构建 html 内容,测试发送 

@Test
public void testHtmlMail() throws Exception {
  String content = "<html>\n" +
      "<body>\n" +
      "  <h3>hello world ! 这是一封Html邮件!</h3>\n" +
      "</body>\n" +
      "</html>";
  MailService.sendHtmlMail("wuguangnuo@qq.com", "test simple mail", content);
}

发送带附件的邮件:在 MailService 添加 sendAttachmentsMail 方法

public void sendAttachmentsMail(String to, String subject, String content, String filePath) {
  MimeMessage message = mailSender.createMimeMessage();

  try {
    MimeMessageHelper helper = new MimeMessageHelper(message, true);
    helper.setFrom(from);
    helper.setTo(to);
    helper.setSubject(subject);
    helper.setText(content, true);

    FileSystemResource file = new FileSystemResource(new File(filePath));
    String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
    helper.addAttachment(fileName, file);

    mailSender.send(message);
    logger.info("带附件的邮件发送成功");
  } catch (MessagingException e) {
    logger.error("带附件的邮件发送异常!", e);
  }
}

(添加多个附件可以使用多条 helper.addAttachment(fileName, file)

@Test
public void sendAttachmentsMail() {
    String filePath="e:\\tmp\\application.log";
    mailService.sendAttachmentsMail("wuguangnuo@qq.com", "带附件的邮件", "有附件,请查收!", filePath);
}

发送带静态资源的邮件:邮件中的静态资源一般就是指图片,在 MailService 添加 sendAttachmentsMail 方法

public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId) {
  MimeMessage message = mailSender.createMimeMessage();

  try {
    MimeMessageHelper helper = new MimeMessageHelper(message, true);
    helper.setFrom(from);
    helper.setTo(to);
    helper.setSubject(subject);
    helper.setText(content, true);

    FileSystemResource res = new FileSystemResource(new File(rscPath));
    helper.addInline(rscId, res);

    mailSender.send(message);
    logger.info("嵌入静态资源的邮件已经成功");
  } catch (MessagingException e) {
    logger.error("嵌入静态资源的邮件发送异常!", e);
  }
}

添加多个图片可以使用多条 <img src='cid:" + rscId + "' > 和 helper.addInline(rscId, res) 来实现 

@Test
public void sendInlineResourceMail() {
    String rscId = "neo006";
    String content="<html><body>这是有图片的邮件:<img src=\'cid:" + rscId + "\' ></body></html>";
    String imgPath = "D:\\tmp\\favicon.png";

    mailService.sendInlineResourceMail("wuguangnuo@qq.com", "这是有图片的邮件", content, imgPath, rscId);
}

到此所有的基本邮件发送服务已经完成了。