ホーム > programming > Velocityでメール送信

Velocityでメール送信

2009 年 5 月 17 日 コメントをどうぞ コメント

メール全体のフォーマットが決まっていて、その一部だけを動的に変更してメールを送信する場合、Apache Velocity を利用したほうが便利。

Velocity はJavaベースの汎用テンプレートエンジンです。Webページ生成、ソースコード・設定ファイルの自動生成など様々な用途で利用可能です。Uprush の場合は、コンテンツ編集画面がJSP以外、他のページは全てVelocityを使って生成されている。

  • メール本文

ここで、Velocity を使って、Uprush のコメントお知らせメールを生成する。生成するメールは下記の通りです。

将太郎 様 
 
Uprush よりお知らせです。 
 
投稿されたコンテンツ 「Velocityでメール送信」 にコメントが寄せられてきました。 
以下の URL よりご確認してください。 
 
確認 URL↓ 
http://uprush.net/node/33 
 
===================================================================== 
■このメールをお送りしているアドレスは送信専用となっており、 
返信していただいても回答いたしかねます。 
 
■発行      Uprush 
■ホームページ http://uprush.net/ 
■お問合せ   webmaster@uprush.net 
Copyright(C) Uprush. All rights reserved 
===================================================================== 

 

  • テンプレート

上記メールのなか、会員名、コンテンツ名と確認URLは動的な内容です。このメールのテンプレート・ファイルは下記 mailComment.vm です。

$nickname 様 
 
Uprush よりお知らせです。 
 
投稿されたコンテンツ 「$bookName」 にコメントが寄せられてきました。 
以下の URL よりご確認してください。 
 
確認 URL↓ 
$url 
 
===================================================================== 
■このメールをお送りしているアドレスは送信専用となっており、 
返信していただいても回答いたしかねます。 
 
■発行      Uprush 
■ホームページ http://uprush.net/ 
■お問合せ   webmaster@uprush.net 
Copyright(C) Uprush. All rights reserved 
===================================================================== 

 

テンプレート・ファイルを読み込んで、テンプレート内の変数に値を入れ替えのJavaメソッドです。

public String sendTemplate(String to, String subject, String vm, Map<String, Object> value) throws Exception{ 
   StringWriter sw = 
null
   
try { 
       String propertyFile = _rb.getString(
"velocity.properties"); 
       Velocity.init(propertyFile); 
 
       VelocityContext context = 
new VelocityContext(); 
       
for(String key : value.keySet()) { 
           context.put(key, value.get(key)); 
       } 
       Template template = 
null
 
       template = Velocity.getTemplate(vm); 
 
       sw = 
new StringWriter(); 
       template.merge( context, sw ); 
       sw.flush(); 
       String msg = sw.toString(); 
 
       Collection<String> toList = 
new ArrayList<String>(); 
       toList.add(to); 
       String from = _rb.getString(
"mail.from"); 
       String fromName = _rb.getString(
"mail.fromName"); 
 
       
return send(toList, nullnull, from, fromName, subject, msg); 
   } 
finally { 
       
if (sw != null) { 
           sw.close(); 
       } 
   } 

 

「_rb.getString("velocity.properties")」はVelocityの設定ファイルを取得する、例えば 「src/resource/velocity.properties」です。velocity.properties には、テンプレートの文字コードとテンプレートファイルを配置するディレクトリのパスを設定している。

velocity.properties の内容の抜粋。

resource.loader=file 
file.resource.loader.description = Velocity File Resource Loader 
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader 
file.resource.loader.path = /home/uprush/workspace/uprush/vm 
 
input.encoding=UTF-8 
output.encoding=UTF-8 
default.contentType=text/html;charset=UTF-8 

 

  • Apache Commons Email の利用

メール送信はApache Commons Emailを 利用する。僕は使っているCommons Emailのバージョンが古いかもしれないが、日本語メールを送信する際に、本文が文字化けしてしまった。Commons Emailを直接使ってはいけないそうです(すでにバグ報告済みらしい)。Commons EmailはAPL2ライセンスでソースを公開しているので、この文字化けの問題は org.apache.commons.mail.SimpleEmail のソースを修正し再コンパイルで解決できる。

org.apache.commons.mail.SimpleEmail のsetMsgメソッドを、メール本文の charset を指定するように修正した後のソースです。

public Email setMsg(String msg) throws EmailException 

    
if (EmailUtils.isEmpty(msg)) 
    { 
        
throw new EmailException("Invalid message supplied"); 
    } 
 
    String useCharset = (charset == 
null ? TEXT_PLAIN : TEXT_PLAIN + "; charset=" + charset); 
    setContent(msg, useCharset); 
 
    
// setContent(msg, TEXT_PLAIN); 
    
return this

 

  • メール送信

最後はCommons Emailを呼び出して、メールを送信する。

public String send(Collection<String> to, Collection<String> cc, Collection<String> bcc, String from, 
        String fromName, String subject, String msg) 
throws Exception{ 
 
    
try { 
        
// host を取得 
        String host = _rb.getString(
"mail.host"); 
        String charset = _rb.getString(
"mail.charset"); 
 
        
// メール設定 
        SimpleEmail mail = 
new SimpleEmail(); 
        mail.setHostName(host); 
        mail.setCharset(charset); 
        
for (String toAddr : to) { 
            mail.addTo(toAddr); 
        } 
        
if (cc != null) { 
            
for (String ccAddr : cc) { 
                mail.addCc(ccAddr); 
            } 
        } 
        
if (bcc != null) { 
            
for (String bccAddr : bcc) { 
                mail.addBcc(bccAddr); 
            } 
        } 
        mail.setFrom(from, fromName); 
 
        mail.setSubject(subject); 
 
        mail.setMsg(msg); 
        mail.setAuthentication(_rb.getString(
"mail.user"), _rb.getString("mail.password")); 
 
        
return mail.send(); 
 
    } 
catch (EmailException ee) { 
 
        
// 宛先不明であるかどうか 
           Throwable ex = ee.getCause(); 
 
           
do { 
               
if (ex instanceof SendFailedException) { 
                   SendFailedException sfex = (SendFailedException) ex; 
                   Address[] invalid = sfex.getInvalidAddresses(); 
 
                   
if (invalid != null) { 
                    _isAddressError = 
true
                   } 
 
                   Address[] validUnsent = sfex.getValidUnsentAddresses(); 
 
                   
if (validUnsent != null) { 
                    _isAddressError = 
true
                   } 
 
                   Address[] validSent = sfex.getValidSentAddresses(); 
 
                   
if (validSent != null) { 
                    _isAddressError = 
true
                   } 
               }
else if (ex instanceof MessagingException) { 
                   ex = ((MessagingException) ex).getNextException(); 
               } 
else { 
                   ex = 
null
               } 
           } 
while (ex != null); 
           
throw ee; 
    } 

 

Share and Enjoy:
  • del.icio.us
  • Google Bookmarks
  • Facebook
  • FriendFeed
  • Twitter
カテゴリー: programming タグ: ,
  1. コメントはまだありません。
  1. トラックバックはまだありません。