Nous avons des valeurs numériques dans notre base de données, représentant un état à deux valeurs. Bien sûr, cela correspond parfaitement à un booléen, mais Oracle ne possède pas ce type de données. Le type NUMBER (1,0) de la base de données correspond à un type java.lang.Short en Java (parfois, ils utilisaient NUMBER (*, 0) pour représenter les booléens, qui correspondent à java.math.BigDecimal).Comment enregistrer un rendu personnalisé dans JSF?
Comme il est en quelque sorte évident, je veux offrir de la glace: selectBooleanCheckbox dans la vue comme une représentation de la valeur et UIComponent à l'utilisateur. (J'utilise IceFaces comme implémentation JSF)
Puisque certaines personnes qui ont spécifié JSF pensent qu'il est évident de toujours faire correspondre la valeur d'un ice: selectBooleanCheckbox ou dans JSF h: selectBooleanCheckbox à un booléen dans le modèle, donc le rendu du composant appelle jamais convertisseur, même si vous spécifiez un: Issue disscused at java.net
J'ai donc essayé les éléments suivants:
J'ai créé un convertisseur pour spécifier dans la 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";
}
}
Le convertisseur fonctionne correctement pour la phase de rendu (la méthode getAsString est appelée correctement), mais la méthode getAsObject (Ignorer que ce n'est pas correct pour le moment, car il n'est pas appelé, donc il sera corrigé!) n'est jamais appelé, parce que dans le moteur de rendu du UIComponent un convertisseur n'est pas prévu, comme vous pouvez le voir ici (sNIP de 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);
}
donc cela se traduit par une exception IllegalArgumentException, car dans la phase UpdateModelValues, on essaie d'appliquer une valeur booléenne à une valeur numérique (ignorez la confusion BigDecimal/Short ... il s'agit simplement d'un type numérique!).
J'ai donc essayé d'écraser le moteur de rendu par un nouveau comme celui-ci:
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);
}
}
et enregistré comme celui-ci dans les 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>
Je suppose que cela doit être correct , mais la méthode surchargée "getConvertedValue" n'est jamais appelée, pas plus que la méthode getAsObject(), donc je suppose que j'ai fait une erreur en enregistrant le rendu personnalisé, mais je ne trouve plus de documentation ou d'astuces pour le faire correctement et surtout comment trouver la bonne famille de composants (j'ai regardé celui que je utilisez dans icefaces.taglib.xml) et le type de rendu correct.
Je ne veux pas modifier le modèle complet pour cette raison. Des conseils, comment cela peut-il être résolu?
Je cours Mojarra 2.0.2 et ne peux pas trouver 'FacesConfigurator' de mon classpath. Cette classe est-elle uniquement ICEFaces? –