我需要将java.math.BigDecimal
类型的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
使用如下输出组件引用类型<h:outputText value="#{bean.value}">
<f:converter converterId="bigDecimalConverter"/>
</h:outputText>
的关联模型或bean的属性。
bean.value
java.math.BigDecimal
是托管bean中的bean.value
类型。如果null
为getAsString()
,则不会调用value="#{bean.value}"
方法。因此,呈现空输出,其中预期值为零。
此value="#{empty bean.value ? 0 : bean.value}"
需要更改为getAsString()
,以便转换器执行其连贯的任务。
然而,将此条件测试放在EL的所有地方都是非常不友好的。
当目标属性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>
方法。
Discount (0.00%)
当#{bean.value}
返回null
时,转换器转换后会显示 data:image/svg+xml,<svg xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" xmlns%3Axlink%3D"http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink" version%3D"1.1" x%3D"0px" y%3D"0px" width%3D"1180px" height%3D"960px" viewBox%3D"20 0 1180 960" enable-background%3D"new 20 0 1180 960" xml%3Aspace%3D"preserve"><style>.style0{fill%3A%09%23257A80%3B}.style1{stroke-linejoin%3A%09round%3Bstroke%3A%09%2342372F%3Bstroke-linecap%3A%09round%3Bstroke-miterlimit%3A%0910%3Bstroke-width%3A%0930%3Bfill%3A%09none%3B}.style2{fill%3A%09%235B4C41%3B}.style3{stroke-linejoin%3A%09round%3Bstroke%3A%09%2368574A%3Bstroke-linecap%3A%09round%3Bstroke-miterlimit%3A%0910%3Bstroke-width%3A%0920%3Bfill%3A%09none%3B}.style4{stroke-linejoin%3A%09round%3Bstroke%3A%09%235B4C41%3Bstroke-linecap%3A%09round%3Bstroke-miterlimit%3A%0910%3Bstroke-width%3A%0914%3Bfill%3A%09none%3B}.style5{fill%3A%09%234D2A0B%3B}.style6{fill%3A%09%2317A89E%3B}.style7{fill%3A%09%235DC2BB%3B}.style8{stroke-linejoin%3A%09round%3Bstroke%3A%09%2341362F%3Bstroke-linecap%3A%09round%3Bstroke-miterlimit%3A%0910%3Bstroke-width%3A%0940%3Bfill%3A%09none%3B}.style9{stroke-linejoin%3A%09round%3Bstroke%3A%09%2368574A%3Bstroke-linecap%3A%09round%3Bstroke-miterlimit%3A%0910%3Bstroke-width%3A%0930%3Bfill%3A%09none%3B}<%2Fstyle><circle cx%3D"820" cy%3D"460" r%3D"90" class%3D"style0"%2F><path d%3D" M990 630H860c-22 0-40-18-40-40v-70" class%3D"style1"%2F><rect x%3D"970" y%3D"430" width%3D"40" height%3D"450" class%3D"style2"%2F><path d%3D" M1000 670h90c16.5 0 30-13.5 30-30V540" class%3D"style3"%2F><path d%3D" M990 780h-70c-11 0-20-9-20-20v-40" class%3D"style4"%2F><circle cx%3D"990" cy%3D"430" r%3D"20" class%3D"style5"%2F><circle cx%3D"990" cy%3D"350" r%3D"150" class%3D"style6"%2F><circle cx%3D"1120" cy%3D"510" r%3D"80" class%3D"style7"%2F><circle cx%3D"900" cy%3D"690" r%3D"60" class%3D"style6"%2F><circle cx%3D"450" cy%3D"510" r%3D"150" class%3D"style0"%2F><path d%3D" M320 720h80c27.5 0 50-22.5 50-50v-60" class%3D"style8"%2F><rect x%3D"270" y%3D"360" width%3D"60" height%3D"600" class%3D"style2"%2F><path d%3D" M290 600H170c-22 0-40-18-40-40v-90" class%3D"style9"%2F><circle cx%3D"300" cy%3D"360" r%3D"30" class%3D"style5"%2F><circle cx%3D"300" cy%3D"220" r%3D"220" class%3D"style6"%2F><circle cx%3D"130" cy%3D"410" r%3D"110" class%3D"style7"%2F><%2Fsvg>
。
答案 0 :(得分:0)
这是Mojarra特有的。发生此问题是因为当值为null时未调用转换器(请参阅source here)。我在MyFaces实现中测试了相同的代码,结果是总是调用convert,无论值是否为null(可以看到here,第378行)。
因此,如果改变JSF实现不是一种选择,我认为通过OmniFaces的解决方案已经足够了。在最坏的情况下,维护一个使#{convert(bean.value)}
之类的转换比使用内联比较更清晰的功能。