2

Seam 2.2.2、JSF Mojarra 1.2_13-b01-FCS、JBoss 5.1.0 サーバーを使用しています。

タイプ NUMBER として指定された 3 つの列を持つ Oracle テーブルがあります。生成された hibernate マッピングは、エンティティ クラスのこれらの列を java.math.BigDecimal としてマップしました。これらは通貨の値であり、BigDecimal は Java でこれらの値を格納および計算するための推奨される方法のようです。

数値コンバーターを使用して、画面上の値を h:inputText および h:outputText の通貨として使用しようとしています。Javaが例外をスローしたときに、これらの値の1つを更新しようとするまでは正常に動作します:

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());
    }


}
4

1 に答える 1

1

その名前にもかかわらず、<f:convertNumber/>変換されませんBigDecimal... の Javadoc を確認するjavax.faces.convert.NumberConverterと、Long(整数の場合) またはDouble. これは、BigDecimals を NumberFormat で解析するには、 flag を設定する必要があるためですsetParseBigDecimal(true)。そうしないと、NumberFormat オブジェクトは double しか生成しません。

javax.faces.BigDecimalJSF は、使用する代わりに、BigDecimals (適切な名前の ) 用の別のコンバーターを提供し<f:convertNumber/>ます。

<f:converter converterId="javax.faces.BigDecimal" />

そして、変換が機能します。ただし、このコンバーターは ほど柔軟ではありません<f:convertNumber/>。パターンを設定したり、異なるロケールを使用したりすることはできません。したがって、ほとんどの人は独自のコンバーター実装を作成するだけです。

于 2012-07-06T20:47:57.640 に答える