JSF Custom Converter is not called a null value

I created my own converter to output java.math.BigDecimal. When BigDecimal is 0.00 or null , I want to output a dash.

Here is my XHTML

 <p:dataTable value="#{bean.data}" var="item"> <p:column> <h:outputText value="#{item.currentValue}"> <f:converter converterId="my.bigDecimalConverter" /> </h:outputText> </p:column> </p:dataTable> 

I have a problem when # {item.currentValue} has a null getAsString method in the converter is not called.

 @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 ""; } } 

I say that it was not called because I have no errors and no println output when BigDecimal is null . When BigDecimal is not null , it works as expected, and "class = class java.math.BigDecimal" prints out, and when BigDecimal is 0.00, I get -- displayed on the page.

I am using JSF 2.1, Mojarra 2.1.27

I also use the following to test my converter.

 <h:outputText value="#{null}"> <f:converter converterId="my.bigDecimalConverter" /> </h:outputText> 

After reading this question, it would seem that the converter should work with null value. stack overflow

+5
source share
1 answer

The link you posted says that the converter should work with a zero value, but don’t say that the converter will be called in every situation with zero values.

Specifically, it does not say that the converter will be called when it is inside h:outputText , and the value is null.

If you dig into Mojarra sources, you will see:

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

Clearly, a null value will never be converted! And I could not find a workaround.

Then, if you really need your value to be zero (you could return 0 or something else), I think your only chance is to do your own rendering. It is very simple:

You are writing a renderer that overrides a method that matters:

 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; } } 

And then declare the renderer in faces-config.xml:

 <render-kit> <renderer> <component-family>javax.faces.Output</component-family> <renderer-type>javax.faces.Text</renderer-type> <renderer-class>my.HtmlCustomRenderer</renderer-class> </renderer> </render-kit> 

Now your converter will be called with zero values!

Hope this helps!

+4
source

Source: https://habr.com/ru/post/1207334/


All Articles