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