【发布时间】:2016-02-11 18:16:10
【问题描述】:
我需要将java.math.BigDecimal 类型的null 属性值转换为0.00,在任何地方都有指定的小数位数(仅用于显示(<h:outputText>),因此不适用于输入组件)。
下面给出了预期完成这项工作的基本转换器(为简洁起见,货币、百分比、区域设置等已完全排除在外)。
@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 类型的关联模型或bean 的属性。
<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 时,有条件地尝试在该方法中将其设置为0 (BigDecimal.ZERO)?
更新:
getAsString() 方法通过 <o:param> (OmniFaces) 调用。
<h:outputFormat value="Discount ({0}%)">
<o:param value="#{bean.value}">
<f:converter converterId="bigDecimalConverter"/>
</o:param>
</h:outputFormat>
当#{bean.value}返回null时,转换器转换后显示Discount (0.00%)。
【问题讨论】:
-
提供 JSF impl-version 会很有用。
-
它是 Mojarra 2.2.12。在 Apache Tomcat 8.0.27.0、GlassFish 4.1 和 WildFly 10.0.0 上交替测试。
标签: jsf converter bigdecimal