Spring整合freemarker发送邮件

本文介绍如何使用Spring、JavaMail和Freemarker实现带附件及内嵌图片的HTML格式邮件发送,包括环境搭建、代码实现及单元测试。

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


原文  http://blog.youkuaiyun.com/zdp072/article/details/32745335

一. 背景知识

在上一篇博文: 使用JavaMail发送邮件和接受邮件, 我们学习了原生的JavaApi发送邮件, 我们会发现代码比较多, 特别是当邮件内容很丰富的时候, 我们需要在Java中拼装Html, 是不是觉得非常麻烦. 

下面我们使用一种比较简单的方法: spring + javaMail + freemarker, 使用freemarker模板引擎后, 我们就不用再在Java中拼装html.


二. 环境准备

废话不多说了, 下面我们准备下开发环境:

1. 所需Jar包:

spring.jar(2.5), commons-logging.jar, mail.jar, freemarker.jar, spring-webmvc.jar, activation.jar

2. 安装易邮邮件服务器, 这个我们在上一篇博文中有讲过, 这里就不再赘述.

3. D盘中放一张图片 "welcome.gif" 和一个word文件 "欢迎注册.docx" 以填充邮件内容.


三. 代码实现

1. 代码结构图如下:



2. 实体Bean:

  1. /** 
  2.  * 用户对象 
  3.  */  
  4. public class User {  
  5.     private String username;  
  6.     private String password;  
  7.   
  8.     public String getUsername() {  
  9.         return username;  
  10.     }  
  11.   
  12.     public void setUsername(String username) {  
  13.         this.username = username;  
  14.     }  
  15.   
  16.     public String getPassword() {  
  17.         return password;  
  18.     }  
  19.   
  20.     public void setPassword(String password) {  
  21.         this.password = password;  
  22.     }  
  23. }  
/**
 * 用户对象
 */
public class User {
	private String username;
	private String password;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

2. 发邮件业务接口

  1. public interface EmailService {  
  2.     public void sendEmail(User user);  
  3. }  
public interface EmailService {
	public void sendEmail(User user);
}

3. 发邮件实现

  1. public class EmailServiceImpl implements EmailService {  
  2.   
  3.     private JavaMailSender mailSender;  
  4.     private FreeMarkerConfigurer freeMarkerConfigurer;   
  5.     private static final String ENCODING = "utf-8";  
  6.   
  7.     public void setMailSender(JavaMailSender mailSender) {  
  8.         this.mailSender = mailSender;  
  9.     }  
  10.   
  11.     public void setFreeMarkerConfigurer(FreeMarkerConfigurer freeMarkerConfigurer) {  
  12.         this.freeMarkerConfigurer = freeMarkerConfigurer;  
  13.     }  
  14.       
  15.   
  16.     /** 
  17.      * 发送带附件的html格式邮件 
  18.      */  
  19.     public void sendEmail(User user) {  
  20.         MimeMessage msg = null;  
  21.         try {  
  22.             msg = mailSender.createMimeMessage();  
  23.             MimeMessageHelper helper = new MimeMessageHelper(msg, true, ENCODING);  
  24.             helper.setFrom("service@estore.com");  
  25.             helper.setTo("zhangsan@estore.com");  
  26.             helper.setSubject(MimeUtility.encodeText("estore注册成功提示邮件", ENCODING, "B"));  
  27.             helper.setText(getMailText(user), true); // true表示text的内容为html  
  28.               
  29.             // 添加内嵌文件,第1个参数为cid标识这个文件,第2个参数为资源  
  30.             helper.addInline("welcomePic"new File("d:/welcome.gif")); // 附件内容  
  31.               
  32.             // 这里的方法调用和插入图片是不同的,解决附件名称的中文问题  
  33.             File file = new File("d:/欢迎注册.docx");  
  34.             helper.addAttachment(MimeUtility.encodeWord(file.getName()), file);  
  35.         } catch (Exception e) {  
  36.             throw new RuntimeException("error happens", e);  
  37.         }   
  38.         mailSender.send(msg);  
  39.         System.out.println("邮件发送成功...");  
  40.     }  
  41.   
  42.     /** 
  43.      * 通过模板构造邮件内容,参数content将替换模板文件中的${content}标签。 
  44.      */  
  45.     private String getMailText(User user) throws Exception {  
  46.         // 通过指定模板名获取FreeMarker模板实例  
  47.         Template template = freeMarkerConfigurer.getConfiguration().getTemplate("registe.html");   
  48.           
  49.         // FreeMarker通过Map传递动态数据  
  50.         Map<String, String> map = new HashMap<String, String>();   
  51.         map.put("username", user.getUsername()); // 注意动态数据的key和模板标签中指定的属性相匹配  
  52.         map.put("password", user.getPassword());  
  53.           
  54.         // 解析模板并替换动态数据,最终content将替换模板文件中的${content}标签。  
  55.         String htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);  
  56.         return htmlText;  
  57.     }  
  58. }  
public class EmailServiceImpl implements EmailService {

	private JavaMailSender mailSender;
	private FreeMarkerConfigurer freeMarkerConfigurer; 
	private static final String ENCODING = "utf-8";

	public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

	public void setFreeMarkerConfigurer(FreeMarkerConfigurer freeMarkerConfigurer) {
		this.freeMarkerConfigurer = freeMarkerConfigurer;
	}
	

	/**
	 * 发送带附件的html格式邮件
	 */
	public void sendEmail(User user) {
		MimeMessage msg = null;
		try {
			msg = mailSender.createMimeMessage();
			MimeMessageHelper helper = new MimeMessageHelper(msg, true, ENCODING);
			helper.setFrom("service@estore.com");
			helper.setTo("zhangsan@estore.com");
			helper.setSubject(MimeUtility.encodeText("estore注册成功提示邮件", ENCODING, "B"));
			helper.setText(getMailText(user), true); // true表示text的内容为html
			
			// 添加内嵌文件,第1个参数为cid标识这个文件,第2个参数为资源
			helper.addInline("welcomePic", new File("d:/welcome.gif")); // 附件内容
			
			// 这里的方法调用和插入图片是不同的,解决附件名称的中文问题
			File file = new File("d:/欢迎注册.docx");
			helper.addAttachment(MimeUtility.encodeWord(file.getName()), file);
		} catch (Exception e) {
			throw new RuntimeException("error happens", e);
		} 
		mailSender.send(msg);
		System.out.println("邮件发送成功...");
	}

	/**
	 * 通过模板构造邮件内容,参数content将替换模板文件中的${content}标签。
	 */
	private String getMailText(User user) throws Exception {
		// 通过指定模板名获取FreeMarker模板实例
		Template template = freeMarkerConfigurer.getConfiguration().getTemplate("registe.html"); 
		
		// FreeMarker通过Map传递动态数据
		Map<String, String> map = new HashMap<String, String>(); 
		map.put("username", user.getUsername()); // 注意动态数据的key和模板标签中指定的属性相匹配
		map.put("password", user.getPassword());
		
		// 解析模板并替换动态数据,最终content将替换模板文件中的${content}标签。
		String htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
		return htmlText;
	}
}

解决名字乱码问题使用:MimeUtility.encodeText(name, "UTF-8", "B")
因为Email的规范,在smtp传输中不可使用中文字符。所以可以使用内置类的MimeUtility方法encodeText将收件人、发件人名字编码即可。

编码方式有两种:"B"代表Base64、"Q"代表QP(quoted-printable)方式。


注意:

1. 不能将名字和email地址一起编码,如直接编码 "Name " 后当做收件人就会出错。

2. Mail的Subject和Content不需要我们显式的编码,在Set的时候这两项会被javax.mail自动编码。


4. spring核心配置

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  4.     xmlns:tx="http://www.springframework.org/schema/tx"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  6.     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  7.     http://www.springframework.org/schema/aop   
  8.     http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
  9.     http://www.springframework.org/schema/tx   
  10.     http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
  11.               
  12.     <bean id="freeMarker" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
  13.         <property name="templateLoaderPath" value="classpath:" /> <!-- 指定模板文件目录  -->  
  14.         <property name="freemarkerSettings"><!-- 设置FreeMarker环境属性 -->  
  15.             <props>  
  16.                 <prop key="template_update_delay">1800</prop> <!--刷新模板的周期,单位为秒 -->  
  17.                 <prop key="default_encoding">UTF-8</prop> <!--模板的编码格式 -->  
  18.                 <prop key="locale">zh_CN</prop> <!--本地化设置-->  
  19.             </props>  
  20.         </property>  
  21.     </bean>  
  22.   
  23.     <!-- 注意:这里的参数(如用户名、密码)都是针对邮件发送者的 -->  
  24.     <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">  
  25.         <property name="host">    
  26.             <value>localhost</value>    
  27.         </property>    
  28.         <property name="javaMailProperties">    
  29.             <props>    
  30.                 <prop key="mail.smtp.auth">true</prop>    
  31.                 <prop key="mail.smtp.timeout">25000</prop>    
  32.             </props>    
  33.         </property>    
  34.         <property name="username">    
  35.             <value>service</value> <!-- 发送者用户名 -->  
  36.         </property>    
  37.         <property name="password">    
  38.             <value>123</value> <!-- 发送者密码 -->  
  39.         </property>   
  40.     </bean>  
  41.       
  42.     <bean id="emailService" class="com.zdp.service.impl.EmailServiceImpl">  
  43.         <property name="mailSender" ref="mailSender"></property>  
  44.         <property name="freeMarkerConfigurer" ref="freeMarker"></property>  
  45.     </bean>  
  46. </beans>      
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
			
	<bean id="freeMarker" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPath" value="classpath:" /> <!-- 指定模板文件目录  -->
		<property name="freemarkerSettings"><!-- 设置FreeMarker环境属性 -->
			<props>
				<prop key="template_update_delay">1800</prop> <!--刷新模板的周期,单位为秒 -->
				<prop key="default_encoding">UTF-8</prop> <!--模板的编码格式 -->
				<prop key="locale">zh_CN</prop> <!--本地化设置-->
			</props>
		</property>
	</bean>

	<!-- 注意:这里的参数(如用户名、密码)都是针对邮件发送者的 -->
	<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
		<property name="host">  
            <value>localhost</value>  
        </property>  
        <property name="javaMailProperties">  
            <props>  
                <prop key="mail.smtp.auth">true</prop>  
                <prop key="mail.smtp.timeout">25000</prop>  
            </props>  
        </property>  
        <property name="username">  
            <value>service</value> <!-- 发送者用户名 -->
        </property>  
        <property name="password">  
            <value>123</value> <!-- 发送者密码 -->
        </property> 
	</bean>
	
	<bean id="emailService" class="com.zdp.service.impl.EmailServiceImpl">
		<property name="mailSender" ref="mailSender"></property>
		<property name="freeMarkerConfigurer" ref="freeMarker"></property>
	</bean>
</beans>    

5. 模板文件:

  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  2. <html>    
  3.    <head>    
  4.       <meta http-equiv="content-type" content="text/html;charset=utf8">    
  5.    </head>    
  6.    <body>    
  7.             恭喜您成功注册estore!<br/>  
  8.             您的用户名为:<font color='red' size='20'>${username}</font>,    
  9.             您的密码为:<font color='red' size='20'>${password}</font>  <img src='cid:welcomePic'/>  
  10.    </body>    
  11. </html>   
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>  
   <head>  
      <meta http-equiv="content-type" content="text/html;charset=utf8">  
   </head>  
   <body>  
        	恭喜您成功注册estore!<br/>
        	您的用户名为:<font color='red' size='20'>${username}</font>,  
        	您的密码为:<font color='red' size='20'>${password}</font>  <img src='cid:welcomePic'/>
   </body>  
</html> 

6. 单元测试:

  1. public class EmailServiceImplTest {  
  2.     @Test  
  3.     public void testSendEmail() {  
  4.         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
  5.         EmailService emailService = (EmailService) context.getBean("emailService");  
  6.         User user = new User();  
  7.         user.setUsername("zhangsan");  
  8.         user.setPassword("123");  
  9.         emailService.sendEmail(user);  
  10.     }  
  11. }  
public class EmailServiceImplTest {
	@Test
	public void testSendEmail() {
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		EmailService emailService = (EmailService) context.getBean("emailService");
		User user = new User();
		user.setUsername("zhangsan");
		user.setPassword("123");
		emailService.sendEmail(user);
	}
}

7. 效果图如下:



8. 源码下载地址: http://download.youkuaiyun.com/detail/zdp072/7529157


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值