JSF自定义转换器未调用null值

我在输出java.math.BigDecimal时创建了自定义Converter。 当BigDecimal为0.00或null我想输出破折号。

这是我的XHTML

 

我遇到的问题是当#{item.currentValue}为null ,不会调用Converter中的getAsString方法。

 @FacesConverter("my.bigDecimalConverter") public class BigDecimalConverter implements Converter { @Override public String getAsString(FacesContext context, UIComponent component, Object value) { if (context == null || component == null) { throw new NullPointerException(); } if (value == null) { System.out.println("null="); return "--"; } System.out.print("Class=" + value.getClass()); if (value instanceof String) { System.out.println("Str=" + value); return (String) value; } if (value instanceof BigDecimal) { BigDecimal bd = (BigDecimal)value; if (bd.equals(new BigDecimal("0.00"))) { return "--"; } else { return bd.toPlainString(); } } return ""; } } 

我说它没有被调用,因为当BigDecimal为null时我没有错误并且没有println语句输出。 当BigDecimal不为null它按预期工作,并打印出“ Class = class java.math.BigDecimal” ,当BigDecimal为0.00时,我会在页面上输出。

我正在使用JSF 2.1,Mojarra 2.1.27

我还使用以下来测试我的转换器。

    

阅读这个问题,似乎转换器应该使用null值。 https://stackoverflow.com/a/19093197/50262

您发布的链接表明转换器应该使用null但不要说在每种情况下都会使用空值调用转换器。

具体地说,当它h:outputText并且值为null时,它不会说转换器将被调用。

如果你挖掘Mojarra来源,你会看到:

 //Line 355 -- com.sun.faces.renderkit.html_basic.HtmlBasicRenderer //method getCurrentValue Object currentObj = getValue(component); if (currentObj != null) { currentValue = getFormattedValue(context, component, currentObj); } 

很明显,永远不会转换空值! 我找不到解决方法。

然后,如果你真的需要你的值为null(你可以返回0或其他)我认为你唯一的机会是制作一个自定义渲染器。 这很容易:

您编写的渲染器会覆盖重要的方法:

 package my; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; import com.sun.faces.renderkit.html_basic.TextRenderer; public class HtmlCustomRenderer extends TextRenderer { @Override public String getCurrentValue(FacesContext context, UIComponent component) { if (component instanceof UIInput) { Object submittedValue = ((UIInput) component).getSubmittedValue(); if (submittedValue != null) { // value may not be a String... return submittedValue.toString(); } } String currentValue = null; Object currentObj = getValue(component); //Remove the 'if' to call getFormattedValue even if null currentValue = getFormattedValue(context, component, currentObj); return currentValue; } } 

然后我们在faces-config.xml中声明渲染器:

   javax.faces.Output javax.faces.Text my.HtmlCustomRenderer   

现在您的转换器将使用空值调用!

我希望它会有所帮助!