JavaMail

JavaMail是JavaEE平台中用于收发邮件的标准规范,它支持SMTP、POP3和IMAP协议,它基本能够实现一个完整的邮件客户端。不过由于其历史比较古老,API也是设计的也是相对比较繁琐。这里我们简单学习如何基于JavaMail实现邮件发送。

添加Maven依赖

JavaMail包含在JavaEE SDK中,如果我们的工程最终部署到JavaEE应用服务器,引入以下依赖即可。

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>8.0.1</version>
    <scope>provided</scope>
</dependency>

不过如果我们不使用JavaEE平台,我们也可以单独引入如下两个Maven依赖。

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

其中,mail模块是JavaMail相关的类和接口,activation则是JAF相关的代码,它是JavaEE中用于处理MIME类型相关的模块,JavaMail依赖该框架。

发送邮件基本流程

这里我们采用一个普通Java工程演示JavaMail发送邮件的代码。下面例子中,我们发送了一封简单的文本邮件。

package com.gacfox.demo;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

public class Main {
    public static void main(String[] args) throws Exception {
        // SMTP服务器设置
        Properties props = new Properties();
        props.setProperty("mail.transport.protocol", "smtp");
        props.setProperty("mail.smtp.host", "SMTP服务器地址");
        props.setProperty("mail.smtp.port", "SMTP服务器端口");
        props.setProperty("mail.smtp.auth", "true");

        // Session
        Session session = Session.getInstance(props);
        session.setDebug(true);

        // Transport
        Transport transport = session.getTransport();
        transport.connect("登录用户名", "登陆密码");

        // 构造邮件
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("发件人邮箱"));
        message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人邮箱"));
        message.setSubject("测试邮件");
        message.setContent("你好", "text/html;charset=UTF-8");

        // 发送邮件
        transport.sendMessage(message, message.getAllRecipients());
        transport.close();
    }
}

代码中实现发送邮件的基本步骤如下:

  1. 设置一些参数,实际使用时,我们也可以将其存储在.properties文件中
  2. 打开JavaMail的Session会话
  3. 打开Transport,这可以理解为和SMTP服务器之间的连接对象
  4. 构造一封邮件
  5. 调用transport.sendMessage()发送邮件
  6. 关闭Transport

其实我们主要关心的就是发送的邮件如何构造,也就是步骤4,其他部分的代码都是相对比较固定的,实际开发中我们按照例子编写即可。

HTML格式邮件内容

实际上邮件内容通常是HTML富文本,但是熟悉前端的开发人员不要高兴的太早,邮件中是没法引入CSS(但可以用一部分内联样式)、JavaScript的,发个图片也要指定图片文件的所在位置,毕竟邮件这种比较严肃的内容,一般不会做太花哨的格式。我们一般都会写一个HTML模板,然后用类似Velocity等引擎生成文件内容。

下面例子代码用Velocity引擎生成一个表格,然后构造为一个邮件的Message对象。

// 测试数据
List<User> userList = new ArrayList<>();
userList.add(new User("tom", "123456"));
userList.add(new User("jerry", "root"));
userList.add(new User("lucy", "admin"));

// Velocity生成HTML
VelocityEngine engine = new VelocityEngine();
Properties veProps = new Properties();
veProps.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
veProps.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
engine.init(veProps);
Template template = engine.getTemplate("src/main/resources/template.vm");
VelocityContext context = new VelocityContext();
context.put("userList", userList);
StringWriter stringWriter = new StringWriter();
template.merge(context, stringWriter);
String mailMsg = stringWriter.toString();

// 构造邮件
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("发件人邮箱"));
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人邮箱"));
message.setSubject("测试邮件");
message.setContent(mailMsg, "text/html;charset=UTF-8");

HTML模板内容如下。

<!doctype html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>账户信息</title>
</head>
<body>
<h1>账户信息</h1>
<table>
    <thead>
    <tr>
        <td>用户名</td>
        <td>密码</td>
    </tr>
    </thead>
    <tbody>
        #foreach($u in $userList)
        <tr style="background-color:
            #if($velocityCount%2==0)
                    #c3f3c3
            #else
                    #f3c3f3
            #end
                ;">
            <td>$u.username</td>
            <td>$u.password</td>
        </tr>
        #end
    </tbody>
</table>

<p style="color: red;"></p>
</body>
</html>

邮件收到的内容如下图。

有关Velocity的内容,参考Java应用程序开发/Velocity模板引擎相关章节。

发送带图片和附件的邮件

对于更复杂的邮件,通常还会在HTML中包含图片,以及携带邮件的附件,下面例子演示了如何构造这种非常复杂的邮件形式。

// 测试数据
List<User> userList = new ArrayList<>();
userList.add(new User("tom", "123456"));
userList.add(new User("jerry", "root"));
userList.add(new User("lucy", "admin"));

// Velocity生成HTML
VelocityEngine engine = new VelocityEngine();
Properties veProps = new Properties();
veProps.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
veProps.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
engine.init(veProps);
Template template = engine.getTemplate("src/main/resources/template.vm");
VelocityContext context = new VelocityContext();
context.put("userList", userList);
StringWriter stringWriter = new StringWriter();
template.merge(context, stringWriter);
String mailMsg = stringWriter.toString();

// 构造邮件
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("发件人邮箱"));
message.setRecipient(Message.RecipientType.TO, new InternetAddress("收件人邮箱"));
message.setSubject("测试邮件");

MimeMultipart multipart = new MimeMultipart();

// 邮件正文部分
MimeBodyPart main = new MimeBodyPart();
main.setContent(mailMsg, "text/html;charset=UTF-8");
multipart.addBodyPart(main);

// 邮件图片加载
MimeBodyPart image = new MimeBodyPart();
DataHandler imgDataHandler = new DataHandler(new FileDataSource("src/main/resources/1.jpg"));
image.setDataHandler(imgDataHandler);
image.setContentID("img_1.jpg");
multipart.addBodyPart(image);

// 邮件附件加载
MimeBodyPart attach = new MimeBodyPart();
DataHandler attachDataHandler = new DataHandler(new FileDataSource("src/main/resources/新建文本文档.7z"));
attach.setDataHandler(attachDataHandler);
attach.setFileName(MimeUtility.encodeText(attachDataHandler.getName()));
multipart.addBodyPart(attach);

message.setContent(multipart);

在HTML模板中,我们需要使用如下形式引用图片。

<img src="cid:img_1.jpg" />
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap