JSF转换器具有空值

时间:2016-02-11 18:16:10

标签: jsf converter bigdecimal

我需要将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类型。如果nullgetAsString(),则不会调用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>

1 个答案:

答案 0 :(得分:0)

这是Mojarra特有的。发生此问题是因为当值为null时未调用转换器(请参阅source here)。我在MyFaces实现中测试了相同的代码,结果是总是调用convert,无论值是否为null(可以看到here,第378行)。

因此,如果改变JSF实现不是一种选择,我认为通过OmniFaces的解决方案已经足够了。在最坏的情况下,维护一个使#{convert(bean.value)}之类的转换比使用内联比较更清晰的功能。