JSF Custom Converter not called on null value

java, jsf, jsf-2

Solution

The link you posted says that a converter should work with a null but doen't say a converter will be called in every situation with null values.

Concretely it don't says a converter will be called when it is inside a `h:outputText` and the value is null.

If you dig in the Mojarra sources you'll see:

//Line 355 -- com.sun.faces.renderkit.html_basic.HtmlBasicRenderer
//method getCurrentValue

    Object currentObj = getValue(component);
    if (currentObj != null) {
        currentValue = getFormattedValue(context, component, currentObj);
    }

It's clear that a null value will never be converted! And I couldn't find a workaround.

Then if you really need your value to be null (you could return 0 or something) I think your only chance is making a custom renderer. It is very easy:

You write a renderer that overrides the 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 we 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 null values!

I hope it will help!

Problem

I've created custom Converter for when I output java.math.BigDecimal. When the BigDecimal is 0.00 or `null` I want 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> ``` The problem I have is when #{item.currentValue} is `null` the `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'm saying its not called because I get no errors and no `println` statement output when the BigDecimal is `null`. When the BigDecimal is not `null` it works as expected and "Class=class java.math.BigDecimal" gets printed out and when the BigDecimal is 0.00 I do get `--` outputted on the page. I'm using JSF 2.1, Mojarra 2.1.27 I also using the following to test my converter. ``` <h:outputText value="#{null}"> <f:converter converterId="my.bigDecimalConverter" /> </h:outputText> ``` Reading over this question it would seem that a converter should work with a `null` value. https://stackoverflow.com/a/19093197/50262

Original source