TomcatでJSFを使っていると、いつもある仕様に悩まされています。
それは、入力フィールドが空白の場合にバッキングビーンのフィールドの型がString型なら長さが0の文字列として入力され、Integer等の数値型なら0が設定されてしまうということです。
String型の場合はまだ分かるのですが、数値型の場合は入力されなかったのか0が入力されたのか区別がつかないんです。
今まではバッキングビーンのフィールドは全てString型で対応していたのですが気持ち悪いので解決方法を探してみました。
まず、数値型に0を入力されないようにするには環境変数の
org.apache.el.parser.COERCE_TO_ZERO
を false に設定すればいいようです。
僕は起動オプションをいじるのが嫌だったので ServletContextListener で
System.setProperty(”org.apache.el.parser.COERCE_TO_ZERO”, “false”);
としました。
数値型に null が設定されるようにするにはこれだけでいいみたいですが、String型に null が設定されるようにするには専用のコンバータを作成する必要があります。
まず、faces-config.xml に String型に対するコンバータを設定します。
<converter> <converter-for-class>java.lang.String</converter-for-class> <converter-class>your.package.StringConverter</converter-class> </converter>
次に、コンバータの本体を作ります。
public class StringConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
return value;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return null;
}
return value.toString();
}
}
これで、String型のフィールドに対する値が入力されなかった場合は長さが0の文字列ではなく null が代入されるようになります。
参考:JSF input conversion - empty string becomes zero instead of null
