データベースには、2 つの値の状態を表す数値があります。もちろん、これはブール値に完全に一致しますが、オラクルにはそのようなデータ型はありません。データベースの NUMBER(1,0) 型は、Java の java.lang.Short 型に一致します (Java.math.BigDecimal に一致するブール値を表すために NUMBER(*,0) を使用することもありました)。
なんとなく明らかなので、ビューで ice:selectBooleanCheckbox を値表現と UIComponent としてユーザーに提供したいと思います。(私はJSF実装としてIceFacesを使用しています)
JSF を指定した一部の人々は、常に ice:selectBooleanCheckbox または JSF の h:selectBooleanCheckbox の値をモデルのブール値に一致させることが明らかであると考えているため、コンポーネントのレンダラーはコンバーターを指定しても、コンバーターを呼び出しません。 java.net で議論されている問題
したがって、私は次のことを試しました:
UIComponent で指定するコンバーターを作成しました。
public class BooleanBigDecimalConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String str) {
if (StringUtils.isEmptyString(str)) {
return new BigDecimal(0);
}
if (str.equals("true")) {
return new BigDecimal(1);
} else {
return new BigDecimal(0);
}
}
public String getAsString(FacesContext context, UIComponent component, Object obj) {
if (obj != null) {
String str = obj.toString();
if (str.equalsIgnoreCase("1")
|| str.equalsIgnoreCase("yes")
|| str.equalsIgnoreCase("true")
|| str.equalsIgnoreCase("on")) {
return "true";
} else {
return "false";
}
}
return "false";
}
}
コンバーターはレンダリング フェーズでは正常に動作しますが (getAsString メソッドは正しく呼び出されます)、getAsObject メソッド (現時点では正しくないことは無視してください。とにかく呼び出されないため、呼び出されれば修正されます!)ここでわかるように、UIComponent のレンダラーではコンバーターが予見されないため、呼び出されませんでした (com.icesoft.faces.renderkit.dom_html_basic.CheckboxRenderer から抜粋):
public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue) throws ConverterException
{
if(!(submittedValue instanceof String))
throw new ConverterException("Expecting submittedValue to be String");
else
return Boolean.valueOf((String)submittedValue);
}
そのため、UpdateModelValues フェーズではブール値を数値に適用しようとするため、IllegalArgumentException が発生します (BigDecimal/Short の混乱は無視してください... いずれにしても単なる数値型です!)。
そこで、次のような新しいレンダラーでレンダラーを上書きしようとしました。
import com.icesoft.faces.component.ext.renderkit.CheckboxRenderer;
public class CustomHtmlSelectBooleanCheckbox extends CheckboxRenderer {
public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
Converter converter = ((ValueHolder) component).getConverter();
return converter.getAsObject(context, component, (String) submittedValue);
}
}
そして、faces-config.xml に次のように登録しました。
<render-kit>
<renderer>
<component-family>com.icesoft.faces.HtmlSelectBooleanCheckbox</component-family>
<renderer-type>com.icesoft.faces.Checkbox</renderer-type>
<renderer-class>com.myapp.web.util.CustomHtmlSelectBooleanCheckbox</renderer-class>
</renderer>
</render-kit>
これは正しいはずだと思いますが、オーバーライドされたメソッド「getConvertedValue」は決して呼び出されず、getAsObject() メソッドも呼び出されないため、カスタム レンダラーの登録を間違えたと思いますが、それ以上のドキュメントが見つからないか、これを適切に行う方法、特に正しいコンポーネント ファミリ (icefaces.taglib.xml で使用するものを調べました) と正しいレンダラー タイプを見つける方法を示します。
このため、完全なモデルを編集したくありません。ヒント、これをどのように解決できますか?