【问题标题】:JSF Currency mapped as NUMBER on the databaseJSF 货币在数据库上映射为 NUMBER
【发布时间】:2012-07-06 00:57:15
【问题描述】:

我正在使用 Seam 2.2.2、JSF Mojarra 1.2_13-b01-FCS、JBoss 5.1.0 服务器。

我有一个 Oracle 表,其中三列指定为 NUMBER 类型。生成的休眠映射已将实体类中的那些列映射为 java.math.BigDecimal。这些是货币值,BigDecimal 似乎是在 Java 中存储和计算这些值的首选方式。

我正在尝试使用数字转换器将屏幕上的值用作 h:inputText 和 h:outputText 中的货币。在我尝试更新其中一个值之前工作正常,当 java 抛出异常时:

EquipItemEdit.xhtml value="#{equipItemHome.instance.cost}": java.lang.IllegalArgumentException: 参数类型不匹配

我的实体映射如下:

@Entity
@Table(name = "EQUIP_ITEM")
public class EquipItem implements java.io.Serializable {
  ...

    private BigDecimal cost;
  ...

        @Column(name = "COST", precision = 22, scale = 0)
    public BigDecimal getCost() {
        return this.cost;
    }

    public void setCost(BigDecimal cost) {
        this.cost = cost;
    }

  ...
}

数据库中的表定义

CREATE TABLE EQUIP_ITEM
(
  EQUIP_ID      NUMBER,
  COUNTER       NUMBER,
  ITEM          VARCHAR2(6 BYTE),
  ACQADC        VARCHAR2(1 BYTE),
  COG           VARCHAR2(2 BYTE),
  COST          NUMBER,
  NOMENC        VARCHAR2(40 BYTE),
  QUA_AUTH      NUMBER,
    ...
)

以及该字段是如何映射到 JSP 上的:

...
<h:inputText id="cost"
 styleClass="value"
          value="#{equipItemHome.instance.cost}"
           size="15">
    <f:convertNumber type="currency" currencySymbol="$" locale="en_US"/>                                        
</h:inputText>
...

有什么建议,或者有人可以指出处理这种数据类型的正确方法吗?


现在为了让事情正常工作,我编写了自己的转换器。还没有做太多的测试,希望有人能告诉我如何让 JSF 内置转换器为此工作。

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.intercept.BypassInterceptors;

@Name("usDollarsConverter")
@BypassInterceptors
@org.jboss.seam.annotations.faces.Converter
public class UsDollarsConverter implements javax.faces.convert.Converter, Serializable {

    public Object getAsObject(FacesContext context, UIComponent component, String     string) {
        if(string == null) {
            return null;
        }       

        try {
            NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);          
            nf.setMinimumFractionDigits(2);
            nf.setMaximumFractionDigits(2);         
            Object value = nf.parse(string);
            if(value instanceof Double) {
                value = new BigDecimal((Double)value);
            } else if(value instanceof Long) {
                value = new BigDecimal((Long) value);
            }
            return value;
        } catch (ParseException e) {
            return null;
        }           

    }

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

        if(value instanceof Double) {
            value = new BigDecimal((Double)value);
        } else if(value instanceof Long) {
            value = new BigDecimal((Long) value);
        }



        if(value instanceof BigDecimal) {
            NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);          
            nf.setMinimumFractionDigits(2);
            nf.setMaximumFractionDigits(2);         
            return nf.format(((BigDecimal)value).doubleValue());            
        }

        throw new java.lang.IllegalArgumentException("UsDollarsConverter requires a type java.math.BigDecimal, will not work with " +     value.getClass().getCanonicalName());
    }


}

【问题讨论】:

    标签: java jsf seam


    【解决方案1】:

    尽管有它的名字,&lt;f:convertNumber/&gt; 不会转换 BigDecimal...如果您检查 Javadoc 中的 javax.faces.convert.NumberConverter,它会告诉您它将生成 Long(用于整数)或 Double .这是因为,要使用 NumberFormat 解析 BigDecimals,您需要设置一个标志 setParseBigDecimal(true),否则 NumberFormat 对象只会产生双精度数。

    JSF 确实为 BigDecimals 提供了一个单独的转换器(恰当地命名为 javax.faces.BigDecimal),而不是 &lt;f:convertNumber/&gt; 使用:

    &lt;f:converter converterId="javax.faces.BigDecimal" /&gt;

    并且转换将起作用。但是,此转换器不如 &lt;f:convertNumber/&gt; 灵活,您不能设置模式或使用不同的语言环境等。因此,大多数人只是编写自己的转换器实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-17
      • 2018-06-23
      • 1970-01-01
      相关资源
      最近更新 更多