【问题标题】:JSF Custom Converter not called on null value未在空值上调用 JSF 自定义转换器
【发布时间】:2015-01-18 20:04:02
【问题描述】:

我为输出 java.math.BigDecimal 创建了自定义转换器。当 BigDecimal 为 0.00 或 null 我想输出一个破折号。

这是我的 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>

我遇到的问题是当#{item.currentValue} 为null 时,转换器中的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

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

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

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

【问题讨论】:

  • 您在使用 Mojarra 吗?哪个具体版本?
  • @fonkap 是的,Mojarra 2.1.27
  • @Tiny 我将转换器更改为带有@RequestScoped@ManagedBean 并删除了@FacesConverter 注释并按照您的建议使用了&lt;f:converter&gt; 中的绑定。除了null 之外,我得到的结果与以前一样。

标签: java jsf jsf-2


【解决方案1】:

您发布的链接说转换器应该与 null 一起使用,但并没有说转换器将在每种情况下都使用 null 值调用。

具体来说,当转换器h:outputText 中并且值为空时,它并没有说会调用转换器。

如果您挖掘 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 中声明渲染器:

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

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

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-15
    • 1970-01-01
    • 2012-12-16
    • 2014-05-22
    • 1970-01-01
    • 2014-03-14
    • 2015-01-02
    相关资源
    最近更新 更多