文章目录
  1. 1. 使用模板语言(Velocity)定义、发送邮件

使用模板语言(Velocity)定义、发送邮件

使用模板语言(Velocity)定义、发送邮件

\

发送邮件时,比如激活邮件、订单邮件等等往往都需要动态数据的填入,比如客户名、订单号,或者密码。类似于web设计:

邮件的模板:是一个可能具有html格式或类似的模板,是View的角色;
邮件的数据:是Model的角色,填入模板,形成最后的邮件内容。

一个与用户交互加多的系统,邮件的种类是“啥都有的”:各种提醒,各种状态告知,。。。
所以基于配置做法相对比较能够统一模式以及省时省力。

我的做法是使用Velocity定义邮件,通过提供良好设计的API,和配置规定实现。最后使用代码大致如下:
  
  /**
   * 激活服务加密解密功能支持
   */
   private  Encryptor encryptor;
  
  /**
   * 激活邮件功能支持
   */
   private  VelocityMailSupport velocityMailSupport;

           public void xxxx(User user) {    
                           Map model = new HashMap();
                           model.put(“user”, user);
                           model.put(“token”, encryptor.encode(user));
                        
**  velocityMailSupport.sendMime(user.getRealname(),   user.getEmail(),
  model);
**  }

velocityMailSupport是一个包含了模板和邮件标题信息的JavaMailSender实现类,sendMime是提供的简易方法,发送具有html样式的代码。\

同时,velocityMailSupport本身使用的内嵌的JavaMailSender是自己实现的PooledMailSender(异步邮件发送)。经过实战使用效果良好。

\

\

附件是核心代码(不是上面的示例代码)和配置:  

VelocityMailSupport.java  
提供给程序使用,通过Spring配置注入到被需要的类中,利用本类可方便发送由Velocity模板生成的邮件内容。客户程序可以组合或继承本类,使具有发送邮件功能。  

PoolMailSender.java  –对Springframework
MailSender和JavaMailSender的装饰,
实现装饰器模式。PooledMailSender将要发送邮件进行排队,按FIFO方式发送得到的邮件消息。  

applicationContext-mail-template.xml  
配置所有的邮件模板的VelocityMailSupport实例,比如激活,找回密码等具体velocity模板和邮件subject  

applicationContext-mail.xml  
基础配置applicationContext-mail-template.xml依赖于它  

mail_template.properties  
配置模板位置和subject文本  



VelocityMailSupport.java  

                

public class VelocityMailSupport implements MailSender,
JavaMailSender{

         //
—————————————————————————–
        
         private Properties mailHeaders = new Properties();

         /**
         *
邮件发送者,包括发送者姓名和地址,用于设置在邮件的from栏目中
         */
         private String from;

         /**
         * 邮件主题
         */
         private String subject;

         /**
         * 邮件内容模板地址/名称
         */
         private String templateName;

         /**
         * velocity引擎
         */
         private VelocityEngine velocityEngine;

         /**
         * mail发送器
         */
         private MailSender mailSender;

         //
—————————————————————————–
        
         /**
         * 日志
         */
         protected static final Log log = LogFactory
                             .getLog(VelocityMailSupport.class);
        
         //
—————————————————————————–

         /**
         * 使用提供的数据,套入velocity模板,生成最后文本信息。
         *
         * 大部分情况下,这个信息应该就是邮件的内容。
         */
         public String renderText(Map model) throws VelocityException {
                   return
VelocityEngineUtils.mergeTemplateIntoString(getVelocityEngine(),
                                       getTemplateName(), model);
         }
        

         //
—————————————————————————–
         //省略getter和setter
         /**
         *
         * 发送Mime邮件简易方法。
         *
         *
以Mime的方式发送邮件,这主要是为能够支持发送html或类似功能(非简单文本)的邮件
         *
         * param nameOfTo 邮件接收收人姓名 或 昵称
         * param emailOfTo 邮件接收人邮件地址
         * param model 邮件velocity模板中变量的值
         * throws MailException
         */
         public void sendMime(String nameOfTo, String emailOfTo, Map
model) throws MailException {
                   sendMime(nameOfTo + “<” + emailOfTo + “>”,
model);
         }

        
         /**
         *   发送Mime邮件简易方法。
         *
         *
以Mime的方式发送邮件,这主要是为能够支持发送html或类似功能(非简单文本)的邮件
         *
         * param to 邮件接收人邮件地址以及可能的收件人姓名或昵称
         * param model 邮件velocity模板中变量的值
         */
         public void sendMime(String to, Map model) throws MailException
{
                   sendMime(mergeSimpleMessage(to, model));
         }
        

         /**
         * 发送Mime邮件简易方法。
         *
         *
以Mime的方式发送SimpleMailMessage,这主要是为能够支持发送html或类似功能(非简单文本)的邮件
         *
         * param simpleMessage
         * throws MailException
         */
         public void sendMime(SimpleMailMessage simpleMessage) throws
MailException {
                   send(toMimeMessage(simpleMessage));
         }
        

        
//———————————————————————————-
        
         public SimpleMailMessage mergeSimpleMessage(String to, Map
model) {
                   //render text of mail from velocity template with the
data
                   String text = null;
                   try {
                             text = renderText(model);
                   } catch (VelocityException e) {
                             log.error(e);
                             e.printStackTrace();
                   }
                  
                   //mail message setting
                   SimpleMailMessage message = new SimpleMailMessage();
                   message.setSubject(getSubject());
                   message.setFrom(getFrom());
                   message.setTo(to);
                   message.setText(text);
                   return message;
         }
        
         /**
         *
         * param simpleMailMessage
         * return
         */
         public MimeMessage toMimeMessage(SimpleMailMessage
simpleMailMessage) {
                   MimeMessage mimeMessage =
createMimeMessage();        
                   MimeMailMessage mmm = new
MimeMailMessage(mimeMessage);
                   simpleMailMessage.copyTo(mmm);
                   return mmm.getMimeMessage();
                            
         }

        
//———————————————————————————-
         // MailSender接口实现 - 代理到配置的实际mailSender
–仅发布一个代理方法,其它省略
         public void send(SimpleMailMessage simpleMessage) throws
MailException {
                   getMailSender().send(simpleMessage);
         }


        
//———————————————————————————-

        
         protected void injectMailHeader(MimeMessage mm){
                   for (Object name : mailHeaders.keySet()) {
                             try {
                                       mm.setHeader((String)name,
mailHeaders.getProperty((String)name));
                             } catch (MessagingException e) {
                                       e.printStackTrace();
                             }
                   }
                  
         }

}//end




PooledMailSender.java



public class PooledMailSender implements MailSender, JavaMailSender,
                   Runnable {

         //
————————————————————————-

         /**
         *
实际发送邮件的邮件发送器,可以是MailSender,或JavaMailSender
         */
         private MailSender mailSender;
        
         //
————————————————————————-
        
         /**
         * 日志
         */
         protected static final Log log = LogFactory
                             .getLog(PooledMailSender.class);

        
         /**
         * 邮件排队点号、发送线程,
         */
         private Thread thread;

         /**
         * 邮件排队队列
         */
         private Queue
queue = new LinkedBlockingQueue
();
        
         /**
         * 锁,仅此而已
         *  
         * see #run()
         * see #add(Object)
         */
         private Object mutex = new Object();

         //
————————————————————————-

         /**
         * 构造本类对象,同时启动侦听邮件的到达。
         *
         *
如果要阻止侦听和发送,应该调用close方法,在Spring的Context中”最好”配置destroy-method=”close”,不过这不是必须的。
         *
         */        
         public PooledMailSender() {
                   thread = new Thread(this);
                   thread.setDaemon(true);
                   thread.start();
         }

       //
————————————————————————-
      
         /**
         * 邮件发送循环,它被作为thread runnable的run实现。
         *
         * see #add(Object)
         *
         */
         public void run() {
                   while (!isClose()) {
                             if (!isEmpty()) {
                                       Object object = poll();
                                       try {
                                                 //执行实际发送
                                                 doSend(object);
                                       } catch (Exception ex) {
                                                 log.error(ex);
                                                 ex.printStackTrace();
                                       }
                             }
                             //等~直到add方法的通知!
                             synchronized (mutex) {
                                       try {
                                                 mutex.wait();
                                       } catch (InterruptedException e)
{
                                       }
                             }
                   }
         }

         //
————————————————————————-

         public MailSender getMailSender() {
                   return mailSender;
         }

         /**
         * 设置实际的邮件发送器
         *
         * param mailSender
         */
         public void setMailSender(MailSender mailSender) {
                   this.mailSender = mailSender;
         }


         //
————————————————————————-

         /**
         * 关闭PooledMailSender!
         *
         * 关闭的PooledMailSender不可再接收和发送邮件
         */
         public void close() {
                   queue.clear();
                   queue = null;
         }

         /**
         * 已经关闭?
         *
         * 关闭的PooledMailSender不可再接收和发送邮件
         *
         * return
         */
         public boolean isClose() {
                   return queue == null;
         }

         //
————————————————————————-
         // 邮件排队机操作方法代理

         protected boolean isEmpty() {
                   return queue != null && queue.isEmpty();
         }
        
         /**
         * 邮件加入排队机
         *
         * param obj
         * see #run()
         */
         protected void add(Object obj) {
                   Assert.notNull(queue);
                   queue.add(obj);
                   //我来了!
                   synchronized (mutex) {
                             mutex.notify();
                   }
         }

         protected Object poll() {
                   Assert.notNull(queue);
                   return queue.poll();
         }

         protected Object peek() {
                   Assert.notNull(queue);
                   return queue.peek();
         }



         //
————————————————————————-
         // MailSender接口实现-将邮件放入排队机
        
         public void send(SimpleMailMessage simpleMessage) throws
MailException {
                   add(simpleMessage);
         }

         public void send(SimpleMailMessage[] simpleMessages) throws
MailException {
                   for (SimpleMailMessage message : simpleMessages) {
                             add(message);
                   }
         }
        
        
         //
————————————————————————-
         // JavaMailSender接口实现-将邮件放入排队机
        
         public void send(MimeMessage mimeMessage) throws MailException
{
                   add(mimeMessage);
         }

         public void send(MimeMessage[] mimeMessages) throws
MailException {
                   for (MimeMessage message : mimeMessages) {
                             add(message);
                   }
         }

         public void send(MimeMessagePreparator mimeMessagePreparator)
                             throws MailException {
                   add(mimeMessagePreparator);
         }

         public void send(MimeMessagePreparator[]
mimeMessagePreparators)
                             throws MailException {
                   for (MimeMessagePreparator preparator :
mimeMessagePreparators) {
                             add(preparator);
                   }
         }

         public MimeMessage createMimeMessage() {
                   return ((JavaMailSender)
mailSender).createMimeMessage();
         }

         public MimeMessage createMimeMessage(InputStream
contentStream)
                             throws MailException {
                   return ((JavaMailSender)
mailSender).createMimeMessage(contentStream);
         }

         //
————————————————————————-
       // 实际发送代理方法
        
         public void doSend(Object object) {
               if (object instanceof SimpleMailMessage) {
                       doSend((SimpleMailMessage) object);
               } else if (object instanceof MimeMessage) {
                       doSend((MimeMessage) object);
               } else if (object instanceof MimeMessagePreparator) {
                       doSend((MimeMessagePreparator) object);
               }
       }

         public void doSend(SimpleMailMessage simpleMessage) throws
MailException {
                   mailSender.send(simpleMessage);
         }
        
         public void doSend(MimeMessage mimeMessage) throws
MailException {
                   ((JavaMailSender) mailSender).send(mimeMessage);
         }

         public void doSend(MimeMessagePreparator
mimeMessagePreparator)
                             throws MailException {
                   ((JavaMailSender)
mailSender).send(mimeMessagePreparator);
         }


}
\

\

\

\

在velocity.properties中设置输入输出编码,例如  


input.encoding=GBK

output.encoding=GBK
default.contentType=text/html; charset=GBK

\

\

\

\

\

\

文章目录
  1. 1. 使用模板语言(Velocity)定义、发送邮件