`
arthur8
  • 浏览: 7336 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Javax mail实现模板邮件发送

阅读更多

       最近,在开发工作中有这么的需求,使用模板技术加javax mail发送模板邮件,经历的一系列的蛋疼时刻终于搞定,在这里做下总结,以备以后在遇到类似问题,方便查找。

     使用VelocityEngine + Spring完成模板解析,VelocityTemplateMailProcessor.java:

    

   
/**
 * 处理velocity邮件模板,将template中参数替换为真实值
 * 
 * @author Arthur
 * 
 */
public class VelocityTemplateMailProcessor implements TemplateMailProcessor {

	private final static Logger LOGGER = Logger
			.getLogger(VelocityTemplateMailProcessor.class);

	/**
	 * 使用velocity模板引擎处理邮件模板,支持在velocity等模板文件中对时间和数字进行格式化支持
	 * 
	 * @param templateLocation
	 *            邮件模板路径:例如在src/main/resoures下有一个example.tpl文件,
	 *            则起对应的tamplateLocation为example.tpl
	 * @param charsetEncoding
	 *            读取邮件模板使用的charset
	 * @param attributeMap
	 *            模板中对应占位符的值map
	 * @return
	 */
	public String process(String templateLocation, String charsetEncoding,
			Map<String, Object> attributeMap) {
		// First, volidate attributeMap, make sure "dateTool" & "numberTool" not
		// used by application
		this.validate(attributeMap);

		try {
			Properties prop = new Properties();
			prop.put("file.resource.loader.class",
					"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
			// 增加date和number格式化支持
			try {
				VelocityTemplateMailProcessor.class.getClassLoader().loadClass(
						"org.apache.velocity.tools.generic.DateTool");
				LOGGER.info("DateTool 'org.apache.velocity.tools.generic.DateTool' found in classpath and support date format");
				DateTool dateTool = new DateTool();
				attributeMap.put("dateTool", dateTool);
			} catch (ClassNotFoundException e) {
				// not exist, just skip
			}

			try {
				VelocityTemplateMailProcessor.class.getClassLoader().loadClass(
						"org.apache.velocity.tools.generic.NumberTool");
				LOGGER.info("NumberTool 'org.apache.velocity.tools.generic.NumberTool' found in classpath and support numberic format");
				NumberTool numberTool = new NumberTool();
				attributeMap.put("numberTool", numberTool);
			} catch (ClassNotFoundException e) {
				// not exist, just skip
			}

			VelocityEngineFactoryBean factoryBean = new VelocityEngineFactoryBean();
			factoryBean.setVelocityProperties(prop);
			VelocityEngine velocityEngine = factoryBean.createVelocityEngine();
			LOGGER.debug("VelocityEngine initialization is ok");

			return VelocityEngineUtils.mergeTemplateIntoString(velocityEngine,
					templateLocation, charsetEncoding, attributeMap);
		} catch (Exception e) {
			LOGGER.error("use VelocityEngine to process mail template["
					+ "templateLocation" + "] error", e);
			throw new ParseTemplateException(e);
		}
	}

	private void validate(Map<String, Object> attributeMap) {
		if (attributeMap.get("dateTool") != null) {
			throw new IllegalArgumentException(
					"dateTool is reserved field not for application, Please make sure it's not used");
		}

		if (attributeMap.get("numberTool") != null) {
			throw new IllegalArgumentException(
					"numberTool is reserved field not for application, Please make sure it's not used");
		}
	}
}

      ok,使用该类完成邮件模板的解析工作,接着发送邮件,邮件发送类这里就不贴出来了;

      使用javax mail发送邮件时最容易遇到的问题就是邮件内容和标题的乱码,对于内容乱码,相信很多人都遇到过,也都知道怎么解决。

       至于标题乱码有点棘手,需要对邮件title进行Base64编码,防止邮件标题中文乱码,但是这里就需要对使用哪个Base64实现类进行选择,

       不幸的是开始楼主选择了Sun的sun.misc.BASE64Encoder进行encode,结果发现有的邮件乱码,有的邮件正常;好蛋疼!!

       经过楼主的排查,翻阅javax mail源码(MimeMessage、MimeUtility.java、PropUtil.java)发现在MimeMessage.java中:

public void setSubject(String subject, String charset)
			throws MessagingException {
	if (subject == null) {
	    removeHeader("Subject");
	} else {
	    try {
		setHeader("Subject", MimeUtility.fold(9,
		    MimeUtility.encodeText(subject, charset, null)));
	    } catch (UnsupportedEncodingException uex) {
		throw new MessagingException("Encoding error", uex);
	    }
	}
    }

    该方法调用到了MimeUtility.fold()方法

 public static String fold(int used, String s) {
	if (!foldText)
	    return s;

	int end;
	char c;
	// 请注意这里
	// Strip trailing spaces and newlines
	for (end = s.length() - 1; end >= 0; end--) {
	    c = s.charAt(end);
	    if (c != ' ' && c != '\t' && c != '\r' && c != '\n')
		break;
	}
	if (end != s.length() - 1)
	    s = s.substring(0, end + 1);

	// 一下省略啦
	......
    }

       该方法遇到""、\t、\r、\n就会将邮件标题截取,剩余部分默认将其作为邮件内容;

       回过头来,再看下sun.misc.BASE64Encoder.encode(),sun的base64实现完全遵循了Base64(RFC2045~RFC2049)规范,将加密后的字符串每76个字符后插入回车换行符,这就导致了邮件标题base64之后不完整,而且邮件内容多了一部分,导致邮件无法被解析展示。

       最后楼主经过测试使用了apache的Base64实现org.apache.commons.codec.binary.Base64,该实现对加密后的Base64字符串不进行任何回车换行的操作。

       OK,这里把解决邮件标题乱码的部分代码贴出来:

String subject = new String(Base64.encodeBase64("subject".getBytes("UTF-8")));
mailMessage.setSubject("=?UTF-8?B?" + subject + "?=");

 

 

   第一次写博客,写的不好还请轻拍:)

分享到:
评论

相关推荐

    java实现模板邮件发送

    Java 实现模板邮件发送是一项常见的任务,特别是在企业级应用中,用于批量发送通知、报告或者验证码等。在本文中,我们将深入探讨如何使用Java来创建和发送带有模板的电子邮件。 首先,我们需要理解Java中用于邮件...

    基于Java的邮件发送模板

    本篇文章将详细讲解如何利用Java实现邮件发送,并结合Apache的相关库来创建邮件发送模板,以提升效率和用户体验。 首先,JavaMail API是Java中用于处理电子邮件的主要库。它提供了丰富的API,可以用来创建、发送和...

    Java通过内容模板发送邮件,支持附件

    在Java编程领域,发送邮件是一项常见的任务,尤其在企业级应用中,如自动...通过JavaMail API与模板引擎的结合,实现了高效、灵活的邮件发送功能。开发者只需提供必要的配置和数据,即可轻松完成复杂的邮件发送任务。

    java发送HTML模版邮件

    在Java编程环境中,发送HTML模板邮件是一项常见的任务,特别是在企业级应用中,用于发送美观、格式化的通知或营销信息。本项目提供了一个完整的Eclipse工程...希望这个概述能帮助你理解并实现自己的Java邮件发送功能。

    Java发送带模版的邮件示例

    此外,如果发送大量邮件,记得考虑邮件发送频率和并发控制,避免被邮件服务器视为垃圾邮件。 通过学习和理解这些知识点,你将能够利用Java实现在各种场景下发送带模板的邮件功能,为你的应用程序添加更丰富的通信...

    Java实现通过模板发送邮件示例

    4. **编写Java代码发送邮件**: 下面的代码展示了如何使用JavaMail API和FreeMarker来发送模板邮件。 ```java import javax.mail.*; import javax.mail.internet.*; import freemarker.template.Configuration; ...

    ant发邮件所需的jar(activation.jar+javax.mail.jar+mail.jar+commons-email-1.2.jar)

    3. **mail.jar**:在某些情况下,javax.mail.jar可能会包含在名为mail.jar的文件中,它是JavaMail API的完整实现,包含了发送邮件所需的所有组件。 4. **commons-email-1.2.jar**:这是Apache Commons Email库,...

    java 发送带模板的邮件工具类

    `javax.mail`库提供了强大的功能,使得在程序中集成邮件发送变得简单而灵活。只需注意,实际使用时需要根据你的SMTP服务器配置调整`SMTP_HOST`、`SMTP_PORT`、`FROM_ADDRESS`和`FROM_PASSWORD`。同时,确保邮件服务...

    java email邮件发送所需mail相关jar包

    "java email邮件发送所需mail相关jar包"就是这样一个集合,它包含了执行邮件发送所需的类和方法。 邮件发送主要依赖于JavaMail API,这是一个开源的Java库,它提供了与邮件服务器交互的标准API。JavaMail API包括多...

    EmailUtils Java mail 邮件发送

    总的来说,`EmailUtils`是一个实用的工具,它简化了使用`JavaMail`发送邮件的过程,通过配置和模板系统,使得邮件发送更加灵活和高效。在实际开发中,这样的工具类大大提高了代码的可读性和可维护性。

    Java邮件发送

    Java邮件发送是通过Java编程语言实现发送电子邮件的功能。在Java中,这通常涉及到JavaMail API,一个用于处理邮件的开放源代码库。本篇将详细解释如何使用Java发送邮件,重点在于提供的三个类:MailSenderInfo.java...

    java mail 邮件发送

    Java Mail邮件发送是一个在Java应用程序中发送电子邮件的关键技术。它基于JavaMail API,这是一个开源库,提供了丰富的功能来处理SMTP(简单邮件传输协议)、POP3(邮局协议)和IMAP(因特网消息访问协议)等邮件...

    用JAVA发送邮件中带模板和附近的源码

    在Java项目中,我们需要引入几个关键的库来实现邮件发送功能: - `java.util.Properties`: 用于配置邮件会话属性。 - `javax.mail.*`: 包含了用于发送邮件的主要类和接口。 - `javax.activation.*`: 提供了处理数据...

    mail.zipJava邮件资源

    2. `javax.mail.Transport`:负责将邮件发送到邮件服务器。通过调用`Transport.send()`方法,开发者可以将创建好的邮件对象发送出去。 3. `javax.mail.Message`:表示一个邮件消息,包含了邮件的全部内容,如收件人...

    Java-mail.zip_java mail_java 邮件_mail 收件箱_邮件系统_邮箱系统

    JavaMail API 包含了多个关键组件,如`javax.mail`和`javax.mail.internet`包,它们提供了创建、配置、发送和接收邮件的接口和类。例如,`Session`对象是邮件会话的入口点,用于设置SMTP服务器信息、认证凭据和其他...

    JavaMail实现邮件发送的简单封装(包括文本、图片、html、附件)

    JavaMail 是一个强大的开源库,用于在Java应用程序中发送和接收电子邮件。...在这个过程中,理解MimeMessage、Multipart和BodyPart的概念,以及如何配置SMTP服务器参数,是成功实现邮件发送的关键。

    Spring Boot中利用JavaMailSender发送邮件的方法示例(附源码)

    在Spring Boot应用中,利用JavaMailSender发送邮件是一种常见的需求,Spring ...Spring Boot的`spring-boot-starter-mail`模块简化了邮件发送的配置和使用,使得开发者能够更加专注于业务逻辑,而不是底层通信细节。

    springboot实现邮件发送

    在Spring Boot框架中,实现邮件发送功能是一项常见的需求,它能够帮助我们自动化处理通知、确认信息等业务场景。本文将详细讲解如何利用Spring Boot的JavaMailSender接口和相关的配置来实现各种类型的邮件发送,包括...

    java发送邮件简单实现

    下面将详细解释如何在Java中实现邮件发送,以及涉及到的关键知识点。 首先,JavaMail API是Java平台用于处理邮件的核心库,它提供了创建、发送、读取和管理电子邮件的功能。要发送邮件,你需要引入`javax.mail`和`...

    邮件发送系统

    首先,邮件发送系统的核心是SMTP(Simple Mail Transfer Protocol),这是一种用于在互联网上传输电子邮件的标准协议。通过SMTP,系统可以将用户编写或预设的邮件发送到目标邮箱服务器。了解SMTP的工作流程,包括...

Global site tag (gtag.js) - Google Analytics