JSF コンバーター

作成 2004/4/24

コンバーターに関するメモです。

コンバーターは、入力、出力と、バッキングビーン(のプロパティー)の間で、値の変換を行います。 例えば、数値をカンマ区切りで入力、出力したい、日付を特定のフォーマットで入力、出力したい、 といった場合に利用できます。

ここではバッキングビーンとして、HogeBean.javaを利用します。 このビーンでは、String型のs、int型のnum、Date型のdという3つのプロパティーを定義しています。

デフォルトのコンバータ

JSFにはデフォルトのコンバーターとして次のものが最初から用意されています。

次の例はDateTimeConverterを利用する例です。

<h:inputText 
  value="#{hoge.d}" 
  converter="javax.faces.DateTime"/>

UIComponentのタグのconverter属性にコンバータID(※1)を指定しています。 こう指定することで、入力フィールドに、yyyy/MM/dd(※2)形式で入力すると、 バッキングビーンのプロパティーにはDate型として格納されます。

※1 IDはどこに書いてあるのだろう?(クラスフィールドには書いてあるが)
※2 デフォルトのtype("date")から作成されるパターン。詳細は、DateTimeConverterクラスを参照のこと。

もしくは、子要素のconverter要素で指定することもできます。

<h:inputText value="#{hoge.d}"> 
  <f:converter converterId="javax.faces.DateTime" />
</h:inputText>

なお、デフォルトのコンバータを、上記のように利用しても、あまり意味がないので、 しないと思います。デフォルトのコンバータは次のタグで利用することになるでしょう。

コンバータタグ

デフォルトのコンバータタグとして次の2つのものが用意されています。

次の例は、convertDateTimeの利用例です。inputTextでyyyyMMdd形式で入力、 outputTextで別の形式で出力しています。

<h:form>

    <p>a:
    <h:inputText value="#{hoge.d}">
      <f:convertDateTime  
        pattern="yyyyMMdd"/>
    </h:inputText>(yyyyMMdd)

    <p>b:
    <h:outputText value="#{hoge.d}">
      <f:convertDateTime  
        pattern="yyyy年MM月dd日"/>
    </h:outputText>    

    <p><h:commandButton value="GOGO"/>

    <p><h:messages/>
</h:form>

実行画面

なお、convertDateTime(DateTimeConverter)は、バッキングビーンのプロパティーの型はDateである必要があるみたいなので、プロパティーを8桁のStringで持ちたいといった場合には、利用できません。

カスタムコンバータ

コンバータは自分で作成することができます。 ZenkakuConverter.javaは、 入力された英数文字を全角に変換するコンバータです。

次のリストはZenkakuConverter.javaの抜粋です。コンバータは、javax.faces.convert.Converter インターフェイスを実装します。 getAsObject(...)メソッドで入力文字列を変換します(ビュー→バッキングビーン)。 getAsString(...)メソッドで出力文字列に変換します(ビュー←バッキングビーン)。

public class ZenkakuConverter implements Converter{
    
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if(value != null){
            return toZenkaku(value);
        }
        return null;
    }

    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return value.toString();
    }
    
    //...
}

faces-config.xmlでは、次のようにコンバータを登録します。

<converter>
    <converter-id>zenkakuConverter</converter-id>
    <converter-class>hoge.ZenkakuConverter</converter-class>
</converter>

JSF側は次のようにコンバータを使います(デフォルトのコンバータのときと同じです)。

<h:inputText value="#{hoge.s}"
    converter="zenkakuConverter"
/>

あるいは、ネストした書き方も可能です。

<h:inputText value="#{hoge.s}">
    <f:converter converterId="zenkakuConverter"/>
</h:inputText>

実行結果。間違って半角で入力した英数字は自動的に全角に変換されます。

カスタムコンバータのタグ

上の方法ではコンバータにパラメータを渡すことができません。 パラメータをわたすときは、カスタムコンバータ用のタグを作る必要があります(他の方法もあるかも)。

DasokuConverter.java(蛇足コンバータ)は、入力した文字列の後ろに、指定した文字列をつけるタグです。実用性はないですが、まあ例ということで。

このコンバータ用のカスタムタグは、次のようになります(ソース:DasokuConverterTag.java)。ConvertTagを継承し、createConverter()メソッドでコンバータを作成しています。

public class DasokuConvertTag extends ConverterTag{

    private String suffix;

    
    protected Converter createConverter() throws JspException {

        DasokuConverter converter = new DasokuConverter();

        converter.setSuffix(suffix);
                
        return converter;
    }

    public String getSuffix() {
        return suffix;
    }

    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }
}

ソースはRIのConvertNumberTagなどを参考にしました。ConverterTagを継承するといったやり方が、仕様として必要なのか、といったことはわかりませんが、とりあえず動いてはいます。

タグなので、TLDファイルに登録する必要があります。ここではtest.tldを作成しました。ここではカスタムタグ自体の説明はここでは省略します。

JSP側はこんな感じで利用できます。

<%@ taglib uri="WEB-INF/test.tld" prefix="myh" %>

...

<h:inputText value="#{hoge.s}">
    <myh:convertDasoku suffix="と言ってみるテスト"/>
</h:inputText>

実行結果。

なお、上のタグのソースでは、createConverter()メソッドで、Converterクラスをそのままnewしていますが、以下のようにすることで、faces-config.xmlに登録した名前からConverterをひっぱってくることができます。こちらの方が正当な感じ?

public DasokuConvertTag() {
    setConverterId("dasokuConverter");//コンバータのID
}

protected Converter createConverter() throws JspException {

    //DasokuConverter converter = new DasokuConverter();
    DasokuConverter converter = (DasokuConverter)super.createConverter();

    converter.setSuffix(suffix);
            
    return converter;
}

参考

Sun J2EE 1.4 Tutorial
Chapter18 の Using the Standard Converters と Using Custom Objects

cardemoサンプルのcreditCardConverter


Back Top