SpringBoot 使用 Thymeleaf 如何发送带模板的Email邮件

本文介绍了在Spring Boot项目中结合Thymeleaf如何发送带模板的Email邮件,包括授权码获取、pom依赖、邮件服务器配置、端口选择、邮件工具类创建、邮件参数实体类、Controller调用以及HTML模板文件的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot+Thymeleaf发送模板邮件

如何在Spring Boot 应用中发送邮件以及使用简单强大的Thymeleaf模板引擎来制作邮件内容。

一、授权码

常用的电子协议有POP3,SMTP,IMAP,协议的具体区别就不进行详细介绍了。这里选择smtp协议进行演示。
登录邮箱,在设置中找到协议地址,点击开启。授权码只会显示一次,需要保存好。

下面是126邮箱对应的三种协议主机地址:

smtp.126.com
pop.126.com
imap.126.com

二、导入pom依赖

	<!-- 发送邮件 -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-mail</artifactId>
	</dependency>
	<!-- thymeleaf -->
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-thymeleaf</artifactId>
	</dependency>

三、邮件服务器属性配置

通常情况下,如果所需要的依赖在 class path 中都是可用的话,这时候Spring会自动帮你注册一个默认实现的邮件发送服务 (default mail sender service)。 spring.mail.host 属性已经被自动定义了, 所有我们所需要做的事情就是把这个属性添加到我们应用的 application.properties 配置文件中。

为了防止springboot项目打包成jar文件之后,读取不到文件,我们把图片和附件都放在服务器指定路径上,直接读取该文件。

注意:password不是邮箱登录密码,而是第一步中获取的授权码。

#mail
spring.mail.host=smtp.126.com
spring.mail.username=xxx@126.com
spring.mail.password=********
spring.mail.properties.mail.smtp.auth=false
spring.mail.properties.mail.smtp.starttls.enable=false
spring.mail.properties.mail.smtp.starttls.required=false
#html template path (resources/templates/email/template.html)
templatePath=email/template
#mail image path
imagePath=D:\\image\\logo.jpg
#imagePath=/neworiental/web/cpbm/image/logo.jpg
一、默认端口号:25

25端口为SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)服务所开放的,是用于发送邮件。

二、使用465端口发送邮件

465端口是为SMTPS(SMTP-over-SSL)协议服务开放的,这是SMTP协议基于SSL安全协议之上的一种变种它继承了SSL安全协议的非对称加密的高度安全可靠性,可防止邮件泄露。SMTPS和SMTP协议一样,也是用来发送邮件(最重要的一点是阿里云服务器上不能使用25端口发送

有坑:Could not connect to SMTP host: smtp.qq.com, port: 465, response: -1

需要配置 SSL 如下:

spring:
  mail:
    host: smtp.126.com #发送邮件服务器
    username: xxx@126.com #网易邮箱
    password: ********** #客户端授权码
    protocol: smtp #发送邮件协议
    properties.mail.smtp.auth: true
    properties.mail.smtp.port: 465
    properties.mail.smtp.starttls.enable: true
    properties.mail.smtp.starttls.required: true
    properties.mail.smtp.ssl.enable: true #开启SSL
    default-encoding: utf-8
    from: xx@126.com
	properties.mail.debug: true #开启邮件debug				(有打印日志 -- 特详细太多)
三、邮件发送的工具类

参考:https://blog.youkuaiyun.com/xujunkai66/article/details/88545796

/**
 * 发送邮件工具类
 * @author 
 */
@Component
public class SendEmailUtils {
   
	private final static Logger logger = LoggerFactory.getLogger(SendEmailUtils.class); 
 
	@Autowired
	private JavaMailSender javaMailSender;
	@Autowired
	private TemplateEngine templateEngine;
 
/**
	 * html模板邮件
	 * @param from 发件人
	 * @param to 收件人
	 * @param subject 邮件主题
	 * @param emailParam 给模板的参数 
	 * @param template html模板路径(相对路径)  Thymeleaf的默认配置期望所有HTML文件都放在 **resources/templates ** 目录下,以.html扩展名结尾。
	 * @param imagePath 图片/文件路径(绝对路径)
	 * @throws MessagingException
	 */
	public void thymeleafEmail(String from,String[] to, String subject,EmailParam emailParam,String template,String imgPath) throws MessagingException {
   
	    MimeMessage mimeMessage =javaMailSender.createMimeMessage();
		MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
		mimeMessageHelper.setFrom(from);
		mimeMessageHelper.setTo(to);
		mimeMessageHelper.setSubject(subject);
		// 利用 Thymeleaf 模板构建 html 文本
		Context ctx = new Context();
		// 给模板的参数的上下文
			ctx.setVariable("emailParam", emailParam);
		// 执行模板引擎,执行模板引擎需要传入模板名、上下文对象
		// Thymeleaf的默认配置期望所有HTML文件都放在 **resources/templates ** 目录下,以.html扩展名结尾。
		// String emailText = templateEngine.process("email/templates", ctx);
		String emailText = templateEngine.process(template, ctx);
		mimeMessageHelper.setText(emailText, true);
		// FileSystemResource logoImage= new FileSystemResource("D:\\image\\logo.jpg");
		//绝对路径
		FileSystemResource logoImage = new FileSystemResource(imgPath);
		//相对路径,项目的resources路径下
		//ClassPathResource logoImage = new ClassPathResource("static/image/logonew.png");
        // 添加附件,第一个参数表示添加到 Email 中附件的名称,第二个参数是图片资源
		//一般图片调用这个方法
		mimeMessageHelper.addInline("logoImage", logoImage);
		//一般文件附件调用这个方法
//		mimeMessageHelper.addAttachment("logoImage", resource);
		javaMailSender.send(mimeMessage);
		
	 }
}
四、邮件参数实体类EmailParam.java
/**
 * 邮件参数实体类
 * @author 
 */
public class EmailParam {
   
	private String itemName;//产品名称
	private String stuName;//学生姓名
	private String updateContent;//变更操作
	private String updatePerson;//操作人员
	private String updateDate;//操作时间
	private String remarks;//备注
//省略get、set方法
}
五、Controller调用邮件工具类发送邮件
@RestController
@RequestMapping("/test")
public class ItemController {
   
	
	private final Logger log = LoggerFactory.getLogger(ItemController.class);
 
	@Value("${spring.mail.username}")
	private String from;
	@Value("${templatePath}")
	private String templatePath;
	@Value("${imagePath}")
	private String imagePath;
	@Autowired
	private SendEmailUtils sendEmailUtils;
	
	/**
	 * email
	 * @param itemIds
	 * @param response
	 */
	@PostMapping(value ="/email", produces = "text/plain;charset=UTF-8")
	public void testEmaili(String itemIds,HttpServletResponse response/*,
			HttpServletRequest request, HttpSession session,
			@RequestHeader("Authorization") String authToken, Principal puser*/) {
   
		try {
   
			EmailParam emailParam = new EmailParam();
			emailParam.setStuName("张阿牛");
			emailParam.setItemName("亚太银行账目统计");
			emailParam.setUpdateContent("付款到账");
			emailParam.setUpdatePerson("盖茨");
			emailParam.setRemarks("成功到账");
                         //此处to数组输入多个值,即可实现批量发送
			String [] to={
   "**********@163.cn"};
			sendEmailUtils.thymeleafEmail(from, to, "这是一封测试邮件主题", emailParam, templatePath, imagePath);
		} catch (Exception e) {
   
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
六、通过事件监听器监听注册事件并发送邮件

通过监听器自动发送邮件

UserRegisterEvent 事件

import com.base.client.model.entity.BaseUser;
import lombok.Getter;
import org.springframework.context.ApplicationEvent;

/**
 * 用户注册事件
 *
 * @author arjun
 * @date 2020/12/15
 */
@Getter
public class UserRegisterEvent extends ApplicationEvent {
   

    /**
     * 发送内容
     */
    private BaseUser user;

    public UserRegisterEvent(Object source, BaseUser user) {
   
        super(source);
        this.user = user;
    }
}

RegisterSentMailListener 监听器

import com.base.client.model.entity.BaseUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.EventListener;
import org.springframework.core.io.ClassPathResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;


/**
 * @author arjun
 * @date 2020/12/15
 */
@Component
public class RegisterSentMailListener {
   

    @Value("${spring.mail.username}")
    private String sender
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private SpringTemplateEngine templateEngine;

    @EventListener
    public void sentMail(UserRegisterEvent event) throws MessagingException, UnsupportedEncodingException {
   
        BaseUser user = event.getUser();
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        // 发件人设置昵称
        helper.setFrom(new InternetAddress(sender, "系统管理员", "UTF-8"));
        // 收件人
        helper.setTo(user.getEmail());
        // 邮件标题
        helper.setSubject("【邮件通知】:初始口令");
        // 利用Thymeleaf 模板构建HTML文本
        Context context = new Context();
        // 给模板的参数的上下文
        context.setVariable("user", user);
        // 执行模板引擎,执行模板引擎需要传入模板名、上下文对象
        // Thymeleaf的默认配置期望所有HTML文件都放在 **resources/templates ** 目录下,以.html扩展名结尾。
        String emailText = templateEngine.process("email", context);
        helper.setText(emailText, true);
        // 相对路径,项目的resources路径下
        ClassPathResource logoImage = new ClassPathResource("templates/images/logo.png");
        // 一般图片调用这个方法,第一个参数表示添加到 Email 中附件的名称,第二个参数是图片资源
        helper.addInline("logoImage", logoImage);
        mailSender.send(message);
    }

}
七、Html模板文件template.html

Thymeleaf的默认配置期望所有HTML文件都放在 **resources/templates ** 目录下,以.html扩展名结尾。

在项目中的路径:**resources/templates/email/template.html

例如:

<div>
    <p>nick: <span th:text="${emailParam.itemName}">产品</span></p>
    <p>phone: <span th:text="${emailParam.stuName}" >张三</span></p>
    <p>email: <span th:text="${emailParam.updateDate}" >2020</span></p>
    <p>address: <span th:text="${emailParam.remarks}" >北京</span></p>
</div>

样式详见https://blog.youkuaiyun.com/qq_39669058/article/details/90485532
利用拉易网制作邮箱模板:拉易网

附HTML模板(仅供参考)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>邮件通知</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body style="margin-top:0px;margin-bottom:0px;margin-left:0px;margin-right:0px; padding-top:0px;padding-bottom:0px;padding-left:0px;padding-right:0px;">
<table width="100%">
	<tr>
		<td style="width: 100%;">
			<center>
				<table class="content-wrap" style="margin: 0px auto; width: 600px;">
					<tr>
						<td style="
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值