簡體   English   中英

Java 9 javax.money.MonetaryAmount(JSR 354):無法將Pojo轉換為XML,反之亦然

[英]Java 9 javax.money.MonetaryAmount (JSR 354): Unable to convert Pojo to XML and vice versa

我正在使用Rest Api調用將Pojo轉換為XML。

以下是我的代碼段:

TestAccount.java

  import javax.money.MonetaryAmount;

    public class TestAccount {


        private MonetaryAmount paymentAmount;

private String accountNumber;


    public String getAccountNumber() {
        return this.accountNumber;
    }


    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
    }
        public MonetaryAmount getPaymentAmount() {
            return this.paymentAmount;
        }


        public void setPaymentAmount(MonetaryAmount paymentAmount) {
            this.paymentAmount = paymentAmount;
        }

        }

Controller.java

public class Controller extends BaseController {

    @RequestMapping(value = "/javaTest", method = RequestMethod.GET, produces = { "application/xml" })
    public TestAccount testMoneyPackage() {
        TestAccount obj = new TestAccount();
        obj.setAccountNumber("101423");
        obj.setPaymentAmount(MoneyUtilityCls.of(10.898));
        return obj;
    }
}

在瀏覽器上運行網址時

http:// localhost:8080 / api / javaTest

輸出:

<OverdueAccount>
<accountNumber>101423</accountNumber>
<paymentAmount>
<currency>
<context>
<providerName>java.util.Currency</providerName>
<empty>false</empty>
</context>
<defaultFractionDigits>2</defaultFractionDigits>
<currencyCode>USD</currencyCode>
<numericCode>840</numericCode>
</currency>
<number>10.9</number>*****loss of precision*******
<negative>false</negative>
<zero>false</zero>
<precision>3</precision>
<scale>1</scale>
<positiveOrZero>true</positiveOrZero>
<positive>true</positive>
<negativeOrZero>false</negativeOrZero>
<factory>
<defaultMonetaryContext>
<precision>0</precision>
<amountType>org.javamoney.moneta.RoundedMoney</amountType>
<fixedScale>false</fixedScale>
<maxScale>-1</maxScale>
<providerName/>
<empty>false</empty>
</defaultMonetaryContext>
<amountType>org.javamoney.moneta.RoundedMoney</amountType>
<maxNumber/>
<minNumber/>
<maximalMonetaryContext>
<precision>0</precision>
<amountType>org.javamoney.moneta.RoundedMoney</amountType>
<fixedScale>false</fixedScale>
<maxScale>-1</maxScale>
<providerName/>
<empty>false</empty>
</maximalMonetaryContext>
</factory>
<context>
<precision>0</precision>
<amountType>org.javamoney.moneta.RoundedMoney</amountType>
<fixedScale>false</fixedScale>
<maxScale>-1</maxScale>
<providerName/>
<empty>false</empty>
</context>
</paymentAmount>
</OverdueAccount>

如您所見,設置時

od.setPaymentAmount(MoneyUtil.of(10.898));

我越來越失去XML的精度,因為

<number>10.9</number>

還有那些額外的XML標簽?

僅對於MonetaryAmount字段會發生此問題,否則代碼將正常運行。 因此,在不損失精度的情況下將MonetaryAmount字段轉換為Pojo並轉換為XML的正確方法是什么?

您可以共享MoneyUtil / MoneyUtilityCls類的代碼嗎?

我猜想MonetaryAmount的實現是RoundedMoney,默認分數為1,這將導致所描述的行為。

在這種情況下,解決方案是使實用程序返回另一個類(例如,Money)或更改返回的RoundedMoney對象的小數位數。

“用雙精度或浮點數表示的貨幣一開始看起來不錯,因為該軟件會消除微小的誤差,但是當您對不精確的數字執行更多的加,減,乘和除運算時,由於錯誤而導致的精度越來越高加起來。這使得浮點數和加倍數不足以應付金錢,在這種情況下,需要十進制乘以10的冪的完美精度。”

最后,Java具有使用Currency和Money的標准方式!

JSR 354:貨幣和貨幣API

JSR 354提供了一個API,用於表示,傳輸和執行Money和Currency的綜合計算。 您可以從以下鏈接下載:

JSR 354:貨幣和貨幣API下載

該規范包括以下內容:

  1. 用於處理例如金額和貨幣的API
  2. 支持互換實現的API
  3. 用於創建實現類實例的工廠
  4. 金額計算,轉換和格式化的功能
  5. 計划將包含在Java 9中的用於Money和Currencies的Java API。
  6. 所有規范類和接口都位於javax.money。*包中。

JSR 354的示例示例:貨幣和貨幣API:

創建MonetaryAmount並將其打印到控制台的示例如下:

MonetaryAmountFactory<?> amountFactory = Monetary.getDefaultAmountFactory();
MonetaryAmount monetaryAmount = amountFactory.setCurrency(Monetary.getCurrency("EUR")).setNumber(12345.67).create();
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.getDefault());
System.out.println(format.format(monetaryAmount));

使用參考實現API時,所需的代碼要簡單得多:

MonetaryAmount monetaryAmount = Money.of(12345.67, "EUR");
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(Locale.getDefault());
System.out.println(format.format(monetaryAmount));

該API還支持MonetaryAmounts的計算:

MonetaryAmount monetaryAmount = Money.of(12345.67, "EUR");
MonetaryAmount otherMonetaryAmount = monetaryAmount.divide(2).add(Money.of(5, "EUR"));

貨幣單位和貨幣金額

// getting CurrencyUnits by locale
CurrencyUnit yen = MonetaryCurrencies.getCurrency(Locale.JAPAN);
CurrencyUnit canadianDollar = MonetaryCurrencies.getCurrency(Locale.CANADA);

MonetaryAmount具有多種方法,可用於訪問分配的貨幣,數字量,其精度等:

MonetaryAmount monetaryAmount = Money.of(123.45, euro);
CurrencyUnit currency = monetaryAmount.getCurrency();
NumberValue numberValue = monetaryAmount.getNumber();

int intValue = numberValue.intValue(); // 123
double doubleValue = numberValue.doubleValue(); // 123.45
long fractionDenominator = numberValue.getAmountFractionDenominator(); // 100
long fractionNumerator = numberValue.getAmountFractionNumerator(); // 45
int precision = numberValue.getPrecision(); // 5

// NumberValue extends java.lang.Number. 
// So we assign numberValue to a variable of type Number
Number number = numberValue;

可以使用舍入運算符舍入MonetaryAmount:

CurrencyUnit usd = MonetaryCurrencies.getCurrency("USD");
MonetaryAmount dollars = Money.of(12.34567, usd);
MonetaryOperator roundingOperator = MonetaryRoundings.getRounding(usd);
MonetaryAmount roundedDollars = dollars.with(roundingOperator); // USD 12.35

當使用MonetaryAmounts的集合時,可以使用一些不錯的實用程序方法進行過濾,排序和分組。

List<MonetaryAmount> amounts = new ArrayList<>();
amounts.add(Money.of(2, "EUR"));
amounts.add(Money.of(42, "USD"));
amounts.add(Money.of(7, "USD"));
amounts.add(Money.of(13.37, "JPY"));
amounts.add(Money.of(18, "USD"));

自定義MonetaryAmount操作

// A monetary operator that returns 10% of the input MonetaryAmount
// Implemented using Java 8 Lambdas
MonetaryOperator tenPercentOperator = (MonetaryAmount amount) -> {
  BigDecimal baseAmount = amount.getNumber().numberValue(BigDecimal.class);
  BigDecimal tenPercent = baseAmount.multiply(new BigDecimal("0.1"));
  return Money.of(tenPercent, amount.getCurrency());
};

MonetaryAmount dollars = Money.of(12.34567, "USD");

// apply tenPercentOperator to MonetaryAmount
MonetaryAmount tenPercentDollars = dollars.with(tenPercentOperator); // USD 1.234567

資源:

使用JSR 354在Java中處理貨幣和貨幣

研究Java 9 Money and Currency API(JSR 354)

另請參見: JSR 354-貨幣和貨幣

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM