繁体   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