使用@FacesConverter(forClass = BigDecimal.class)覆盖JSF转换器javax.faces.convert.BigDecimalConverter以便使用自定义转换器. [英] Overriding the JSF converter javax.faces.convert.BigDecimalConverter in favor of a custom converter using @FacesConverter(forClass = BigDecimal.class)

查看:152
本文介绍了使用@FacesConverter(forClass = BigDecimal.class)覆盖JSF转换器javax.faces.convert.BigDecimalConverter以便使用自定义转换器.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下通用的BigDecimal转换器(深入检查代码绝对是多余的).

I have the following general BigDecimal converter (deeply reviewing the code is absolutely superfluous).

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

    @Inject
    private CurrencyRateBean currencyRateBean; // Maintains a currency selected by a user in his/her session.

    private static final int scale = 2; // Taken from an enum.

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        if (!StringUtils.isNotBlank(value)) {
            return null;
        }

        try {
            BigDecimal bigDecimal = new BigDecimal(value);
            return bigDecimal.scale() > scale ? bigDecimal.setScale(scale, RoundingMode.HALF_UP).stripTrailingZeros() : bigDecimal.stripTrailingZeros();
        } catch (NumberFormatException e) {
            throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "Message"), e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if (value == null) {
            return "";
        }

        BigDecimal newValue;
        if (value instanceof Long) {
            newValue = BigDecimal.valueOf((Long) value);
        } else if (value instanceof Double) {
            newValue = BigDecimal.valueOf((Double) value);
        } else if (!(value instanceof BigDecimal)) {
            throw new ConverterException("Message");
        } else {
            newValue = (BigDecimal) value;
        }

        final String variant = (String) component.getAttributes().get("variant");

        if (variant != null) {
            if (variant.equalsIgnoreCase("grouping")) {
                DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance();
                formatter.setGroupingUsed(true);
                formatter.setMinimumFractionDigits(scale);
                formatter.setMaximumFractionDigits(scale);
                return formatter.format(newValue);

            } else if (variant.equalsIgnoreCase("currency")) {
                String currency = currencyRateBean.getCurrency();
                DecimalFormat formatter = (DecimalFormat) NumberFormat.getCurrencyInstance(new Locale("en", new String(currency.substring(0, 2))));
                formatter.setDecimalFormatSymbols(formatter.getDecimalFormatSymbols());
                formatter.setCurrency(Currency.getInstance(currency));
                return formatter.format(newValue);
            }
        }

        DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance();
        formatter.setGroupingUsed(false); // Not necessary.
        formatter.setMinimumFractionDigits(scale);
        formatter.setMaximumFractionDigits(scale);
        return formatter.format(newValue);
    }
}

可以按如下使用.

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

根据<f:attribute>variant的值,它将值转换为等价货币($ 123)或使用组的值(11,111).也可以在需要时定义其他标准,即不需要其他类型的格式的单独转换器(如果有).转换器的默认任务是将值四舍五入到小数点后两位.

Depending upon the value of variant in <f:attribute>, it converts the value to either currency equivalent ($123) or a value using groups (11,111). Other criteria may also be defined as and when required i.e separate converters for other types of formats, if any, are not required. The default task of the converter is to round up the value to two decimal points.

为了避免提及,

<f:converter converterId="bigDecimalConverter"/>

converter="#{bigDecimalConverter}"到处都是,转换器类需要装饰,

or converter="#{bigDecimalConverter}" everywhere, the converter class needs to be decorated with,

@FacesConverter(forClass = BigDecimal.class)

这样做,JSF拥有自己的 javax.faces.convert.BigDecimalConverter 提前.我尝试过扩展该类,但没有任何区别.

Doing so, JSF takes its own javax.faces.convert.BigDecimalConverter beforehand. I have tried extending that class but it did not make any difference.

是否可以覆盖默认的JSF javax.faces.convert.BigDecimalConverter,以便通过指定forClass = BigDecimal.class来使用我们自己的转换器,从而无需在任何地方乱搞<f:converter converterId="bigDecimalConverter"/>converter="#{bigDecimalConverter}"?

Is it possible to override the default JSF javax.faces.convert.BigDecimalConverter so that our own converter can be used by specifying forClass = BigDecimal.class so that there is no need to fiddle around with <f:converter converterId="bigDecimalConverter"/> or converter="#{bigDecimalConverter}" anywhere?

推荐答案

通常,覆盖默认转换器(以及验证器,组件和渲染器)时,不能在同一标识符上使用注释.它确实必须在Webapp自己的faces-config.xml中明确注册.

In general, overriding default converters (and validators, components and renderers) can't take place with annotations on the same identifier(s). It really has to be explicitly registered in webapp's own faces-config.xml.

如果您打算覆盖converter="javax.faces.BigDecimal",请这样做:

In case you intend to override converter="javax.faces.BigDecimal", then do so:

<converter>
    <converter-id>javax.faces.BigDecimal</converter-id>
    <converter-class>com.example.YourBigDecimalConverter</converter-class>
</converter>

如果您打算覆盖类型java.math.BigDecimal的隐式转换,请这样做:

In case you intend to override implicit conversion for type java.math.BigDecimal, then do so:

<converter>
    <converter-for-class>java.math.BigDecimal</converter-for-class>
    <converter-class>com.example.YourBigDecimalConverter</converter-class>
</converter>

您需要后者.

这篇关于使用@FacesConverter(forClass = BigDecimal.class)覆盖JSF转换器javax.faces.convert.BigDecimalConverter以便使用自定义转换器.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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