具有空值的JSF转换器 [英] JSF converter with null value

查看:173
本文介绍了具有空值的JSF转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将带有指定位置的小数位数的null类型的null属性值转换为0.00(仅用于显示(<h:outputText>),而不用于输入组件).

I need to convert null property values of type java.math.BigDecimal to 0.00 everywhere with a specified number of decimal places (only for displaying (<h:outputText>) thus, not for input components).

下面给出了预期完成此工作的基本转换器(为简便起见,货币,百分比,语言环境等已完全排除在外).

The basic converter expected to do this job is given below (currency, percentage, locale etc have been excluded completely for brevity).

@FacesConverter("bigDecimalConverter")
public final class BigDecimalConverter implements Converter {

    private static final int SCALE = 2;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {

        if (submittedValue == null || submittedValue.isEmpty()) {
            return null;
        }

        try {
            return new BigDecimal(submittedValue).setScale(SCALE, RoundingMode.HALF_UP).stripTrailingZeros();
        } catch (NumberFormatException e) {
            throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "Message"), e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object modelValue) {

        BigDecimal value;

        if (modelValue == null) { // This is expected to replace null with 0.
            value = BigDecimal.ZERO;
        } else if (modelValue instanceof Long) {
            value = BigDecimal.valueOf((Long) modelValue);
        } else if (modelValue instanceof Double) {
            value = BigDecimal.valueOf((Double) modelValue);
        } else if (!(modelValue instanceof BigDecimal)) {
            throw new ConverterException("Message");
        } else {
            value = (BigDecimal) modelValue;
        }

        NumberFormat numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setGroupingUsed(true);
        numberFormat.setMinimumFractionDigits(SCALE);
        numberFormat.setMaximumFractionDigits(SCALE);
        return numberFormat.format(value);
    }
}

使用类似以下的输出组件引用类型为java.math.BigDecimal的关联模型或bean的属性.

Referring to a property of the associated model or bean of type java.math.BigDecimal using output components like the following.

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

bean.value是托管bean中的java.math.BigDecimal类型.如果bean.valuenull,则不会调用getAsString()方法.因此,将在预期值为零的情况下呈现空输出.

bean.value is a type of java.math.BigDecimal in a managed bean. If bean.value is null, then the getAsString() method is not invoked. Hence, an empty output is rendered where a value of zero is expected.

需要将此value="#{bean.value}"更改为value="#{empty bean.value ? 0 : bean.value}",以便转换器执行其连贯的任务.

This value="#{bean.value}" needs to be changed to value="#{empty bean.value ? 0 : bean.value}" for the converter to perform its coherent task.

但是,将这种有条件的测试放在所有地方的EL中,维护起来非常不友好.

Putting this conditional test in EL everywhere is however, quite maintenance-unfriendly.

当目标属性为null且有条件地尝试在该方法(BigDecimal.ZERO)中尝试将其设置为0时,是否可以调用getAsString()方法?

Is there a way to invoke the getAsString() method, when a target property is null which is conditionally attempted to be set to 0 in that method (BigDecimal.ZERO)?

更新:

getAsString()方法是通过<o:param>(OmniFaces)调用的.

The getAsString() method is invoked with <o:param> (OmniFaces).

<h:outputFormat value="Discount ({0}%)">
    <o:param value="#{bean.value}">
        <f:converter converterId="bigDecimalConverter"/>
    </o:param>
</h:outputFormat>

#{bean.value}返回null时,由转换器转换后,显示Discount (0.00%).

This displays Discount (0.00%) after has been converted by the converter, when #{bean.value} returns null.

推荐答案

这是针对Mojarra的.发生问题是因为在值为null时未调用转换器(请参见此处,第378行).

This is specific to the Mojarra. The problem occurred because the converter is not called when the value is null (see source here). I tested the same code in the MyFaces implementation and the result is that the convert is always called, no matter if the value is null (as can be seen here, line 378).

因此,如果不能选择更改JSF实现,那么我认为通过OmniFaces解决方案就足够了.最糟糕的是,维护一个使转换如#{convert(bean.value)}的函数可以比内联比较使您的视图更清晰.

So if change JSF implementation is not an option, I think the solution through OmniFaces is good enough. At worst, maintain a function that makes the conversion like #{convert(bean.value)} may leave cleaner your view than an inline comparison.

这篇关于具有空值的JSF转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆