Java – JSF custom converter without calling null value
I'm outputting Java math. BigDecimal creates a custom converter When BigDecimal is 0.00 or null, I want to output dashes
This 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>
The problem I encountered is that when #{item. Currentvalue} is null, the getasstring method in the converter will not be 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 said it was not called because I had no errors and no println statement output when BigDecimal was null When BigDecimal is not null, it works as expected and prints "class = class java. Math. BigDecimal". When BigDecimal is 0.00, I will output it on the page
I'm using JSF 2.1, mojarra 2.1 twenty-seven
I also use the following to test my converter
<h:outputText value="#{null}"> <f:converter converterId="my.bigDecimalConverter" /> </h:outputText>
Reading this question, it seems that the converter should use null values https://stackoverflow.com/a/19093197/50262
Solution
The link you post indicates that the converter should use null, but don't say that the converter will be called and null in every case
Specifically, when it is in H: outputtext and the value is null, it does not say that the converter will be called
If you dig into the source of mojarra, 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); }
Obviously, null values will never be converted! I can't find a solution
Then, if you really need your value to be null (you can return 0 or other) I think your only chance is to make a custom renderer This is easy:
The renderer you write overrides important methods:
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,currentObj); return currentValue; } }
Then we're at faces - config Declare renderer in 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 a null value!
I hope it will help!