作成 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