Velocityを用いたメールテンプレート

ある定型のメールの文章のうち、一部分だけを変えて送信したいということは往々にしてあり得ます。しかし、その処理を実装しようと思うと案外面倒だったりします。そこで、その処理を簡単にするために、Apache Velocityを用いたメールテンプレートの利用方法について紹介します。

【前提条件】
- J2SE 1.2以上
- Apache Velocity1.5
- Apache Commons Collection3.1, Apache Commons Lang2.1
- テンプレートファイル(.vm)
- プロパティファイル(.properties):必須ではない。以下の例では利用

【使い方】
Apache VelocityはJ2SE以降で動作する汎用テンプレートエンジンです。これを利用することで、メールテンプレートはもちろん、XMLやSQLなど、あらゆるテンプレートに利用可能です。使い方はアイデア次第といったところです。

で、実際に利用するためにApacheプロジェクトのサイトからjarファイルをダウンロードしてきます。
[web] Apache Velocity

このページの左側に「Downloads」と書かれたリンクがあるので、その先のページからzipファイルかtar.gzファイルをダウンロードします。

そして、ダウンロードしてきたファイルを解凍するとVelocityのjarファイルが手に入ります。ただ単に試したいだけならvelocity-dep-X.jarを利用すればいいでしょう。velocity-X.jarは、Velocityが利用している外部ライブラリを含んでいないjarファイルです。

velocity-dep-X.jarをクラスパスで指定し、以下のプログラムを実行することで動作を確かめられます。Velocityで提供されている主要なクラスは、VelocityContextクラスとVelocityEngineクラスです。

    public static void main(String[] args) throws Exception{
        // 購入者情報
        Member member = new Member();
        member.setLastName( "佐藤" );
        member.setFirstName( "太郎" );
        member.setEmail("aaa@example.com");
        
        // 購入商品情報
        Item item1 = new Item();
        item1.setItemCode("0000-1111" );
        item1.setName( "健康食品1" );
        item1.setPrice(1000);

        Item item2 = new Item();
        item2.setItemCode("0000-1112" );
        item2.setName( "健康食品2" );
        item2.setPrice(2000);
        
        // 注文情報
        Order order = new Order();
        order.setMember( member );
        order.setOrderNumber("0001-AAAA");
        
        order.addItem(item1);
        order.addItem(item2);
        
        // 会社情報
        Company company = new Company();
        company.setName("なんでも.com");
        company.setEmail("bbb@example.com");        
        
        VelocityWrapper va = new VelocityWrapper( "mail.vm" );
        va.put( "order" , order );
        va.put( "company" , company );
        String body = va.merge();
        
        System.out.println(body);  
    }

    public class Company {

	private String name;
	private String email;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
    }

    public class Item {

	private String itemCode;
	private String name;
	private int price;
	
	public String getItemCode() {
		return itemCode;
	}
	public void setItemCode(String itemCode) {
		this.itemCode = itemCode;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int i) {
		this.price = i;
	}
    }

    public class Member {

	private String lastName;
	private String firstName;
	private String email;

	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}	
    }

    public class Order {

	private Member member;
	private String orderNumber;
	private List itemList = new ArrayList();
	
	public Member getMember() {
		return member;
	}
	public void setMember(Member member) {
		this.member = member;
	}
	public String getOrderNumber() {
		return orderNumber;
	}
	public void setOrderNumber(String orderNumber) {
		this.orderNumber = orderNumber;
	}
	public List getItemList() {
		return itemList;
	}
	public void setItemList(List itemList) {
		this.itemList = itemList;
	}
	public void addItem(Item item1) {
		itemList.add(item1);		
	}
    }

    public class VelocityWrapper {

	/** テンプレートファイルの内容を格納したクラス */
	private Template template = null;

	/**
	 * テンプレート変換時に使用する オブジェクトを格納するためのクラス
	 */
	private VelocityContext context = new VelocityContext();

	/** Velocityエンジンにアクセスするためのクラス */
	private VelocityEngine engine = new VelocityEngine();

	public VelocityWrapper(String templateFileName) throws IOException,
			Exception {

		// velocity.propertiesによるVelocityEngineの初期化
		Properties props = new Properties();
		props.load(new FileInputStream("velocity.properties"));
		engine.init(props);

		// テンプレートの取得
		template = engine.getTemplate(templateFileName);
	}

	public void put(String key, Object value) {
		context.put(key, value);
	}

	public String merge() throws ResourceNotFoundException,
			ParseErrorException, MethodInvocationException, Exception {
		StringWriter sw = new StringWriter();
		template.merge(context, sw);
		return sw.toString();
	}
    }
以下がvelocity.propertiesです。
input.encoding=Windows-31J
output.encoding=Windows-31J
以下がテンプレートファイル(mail.vm)です。
$order.member.lastName $order.member.firstName 様

$company.nameをご利用頂きありがとうございます。

以下の注文を承りました。
注文番号:$order.orderNumber

≪購入商品情報≫
-----------------------------
商品番号 |注文商品名|価格
-----------------------------
#set ($amount=0)
#foreach ( $item in $order.itemList)
$item.itemCode|$item.name|  $item.price
#set( $amount=$amount+$item.price)
#end
-----------------------------
         合計          $amount
#set ($point=0)
#if($amount<1000)
#set ($point=10)
#elseif($amount<2000)
#set ($point=20)
#else
#set ($point=30)
#end

獲得ポイントは$pointです。

=================================================
$company.name
メールアドレス:$company.email
=================================================
なお、この記事を書くために、CodeZine様のページをとても参考にさせていただいています。(ただし、本文中の誤記が非常に多いです。)
[web] Jakarta Velicityでテンプレートを変換しメールを送信する - CodeZine

前へ

OpenOffice Calcでグリッド線表示をなくす

次へ

Velocity独自のログ機能を無効にする