空值的JSF转换器
我需要将java.math.BigDecimal
类型的属性值转换为0.00
,并将其指定为小数点后的位置(仅用于显示(<h:outputText>
),因此不适用于输入组件)。空值的JSF转换器
预计完成这项工作的基本转换器在下面给出(为简洁起见,货币,百分比,区域等已被完全排除)。
@FacesConverter("bigDecimalConverter")
public final class BigDecimalConverter implements Converter {
private static final int SCALE = 2;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
return new BigDecimal(submittedValue).setScale(SCALE, RoundingMode.HALF_UP).stripTrailingZeros();
} catch (NumberFormatException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "Message"), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
BigDecimal value;
if (modelValue == null) { // This is expected to replace null with 0.
value = BigDecimal.ZERO;
} else if (modelValue instanceof Long) {
value = BigDecimal.valueOf((Long) modelValue);
} else if (modelValue instanceof Double) {
value = BigDecimal.valueOf((Double) modelValue);
} else if (!(modelValue instanceof BigDecimal)) {
throw new ConverterException("Message");
} else {
value = (BigDecimal) modelValue;
}
NumberFormat numberFormat = NumberFormat.getNumberInstance();
numberFormat.setGroupingUsed(true);
numberFormat.setMinimumFractionDigits(SCALE);
numberFormat.setMaximumFractionDigits(SCALE);
return numberFormat.format(value);
}
}
参照关联的模型或使用输出组件,如以下类型java.math.BigDecimal
的豆的特性。
<h:outputText value="#{bean.value}">
<f:converter converterId="bigDecimalConverter"/>
</h:outputText>
bean.value
处于托管bean的类型java.math.BigDecimal
。如果bean.value
是null
,则不调用getAsString()
方法。因此,一个空的输出会在预期值为零的位置呈现。
此value="#{bean.value}"
需要更改为value="#{empty bean.value ? 0 : bean.value}"
转换器执行其一致的任务。
然而,将这个条件测试放在EL的每个地方都是非常不利于维护的。
有没有办法来调用getAsString()
方法,当目标属性是null
这是有条件地尝试在方法(BigDecimal.ZERO
)设置为0
?
更新:
的getAsString()
方法被调用与<o:param>
(OmniFaces)。
<h:outputFormat value="Discount ({0}%)">
<o:param value="#{bean.value}">
<f:converter converterId="bigDecimalConverter"/>
</o:param>
</h:outputFormat>
这将显示Discount (0.00%)
之后已经由所述转换器转换,当#{bean.value}
返回null
。
这是特定于莫哈拉。发生此问题是因为当值为空时转换器未被调用(请参阅source here)。我在MyFaces实现中测试了相同的代码,结果是转换始终被调用,无论值是否为空(可以看到here,第378行)。
所以如果改变JSF实现不是一个选项,我认为通过OmniFaces的解决方案已经足够好了。在最坏的情况下,保持一个功能,使像#{convert(bean.value)}
这样的转换可能比内联比较更清晰您的视图。
OmniFaces推荐什么方式来抵御这个特殊问题? – Tiny
OmniFaces有自己的[param的实现](https://github.com/omnifaces/omnifaces/blob/master/src/main/java/org/omnifaces/component/output/Param.java#L120),[ o:param](http://showcase.omnifaces.org/components/param),它也会调用转换器,无论该值为null。所以你可以使用这个组件进行转换,就像你在问题更新中演示的那样。但是如果你想要一个简单的转换来显示它的值,我认为像'#{bean.convertNullAsZero(bean。价值)}'会更简单明确地完成工作。 –
提供JSF impl-version会很有用。 –
这是Mojarra 2.2.12。测试Apache Tomcat 8.0.27.0,GlassFish 4.1和WildFly 10.0.0 final。 – Tiny