【问题标题】:BigDecimal has scientific notation in soap messageBigDecimal 在肥皂信息中有科学记数法
【发布时间】:2013-11-21 08:09:02
【问题描述】:

我的网络服务出现了奇怪的问题。 我有对象 OrderPosition,它有一个价格(它是 xsd:decimal,fractionDigits = 9)。 Apache CXF 为我生成代理类,这个字段是 BigDecimal。当我想发送大于 10000000.00000 的值时,soap 消息中的这个字段有科学计数法(例如 1.1423E+7)。

我怎样才能强制该值没有以科学计数法发送。

【问题讨论】:

  • 您使用的是什么绑定(例如 jaxb 等)?
  • 我使用 jaxb 进行 xml 绑定。并且这个字段有注释:@XmlElement(name = "NetPrice", required = true) protected BigDecimal netPrice;
  • github.com/javaee/jaxb-v2/issues/386也许你使用的是旧版本。

标签: java web-services soap xsd


【解决方案1】:

这是可以做到这一点的一种方法。

BigDecimal 有一个将输入数字作为字符串的构造函数。这在使用时会在调用其.toString() 方法时保留输入格式。例如

BigDecimal bd = new BigDecimal("10000000.00000");
System.out.println(bd);

将打印10000000.00000

这可以在 Jaxb XmlAdapters 中使用。 Jaxb XmlAdapters 提供了一种方便的方式来控制/自定义编组/取消编组过程BigDecimmal 的典型适配器如下所示。

public class BigDecimalXmlAdapter extends XmlAdapter{

    @Override
    public String marshal(BigDecimal bigDecimal) throws Exception {
        if (bigDecimal != null){
            return bigDecimal.toString();
        }
        else {
            return null;
        }
    }

    @Override
    public BigDecimal unmarshal(String s) throws Exception {
        try {
            return new BigDecimal(s);
        } catch (NumberFormatException e) {
            return null;
        }
    }
}

这需要在 Jaxb 上下文中注册。 Here is the link 有完整的例子。

【讨论】:

  • toPlainString() 是无需科学记数法转换即可打印值的方法。
【解决方案2】:

@Santosh 谢谢! XMLAdapter 是我所需要的。 此外,正如我在问题中所说,我使用 Apache CXF 生成客户端类。在这种问题中,我必须将以下代码添加到 bindings.xjb(用于 maven 中的 cxf-codegen-plugin 的绑定文件)。

<jaxb:javaType  name="java.math.BigDecimal" xmlType="xs:decimal"
    parseMethod="sample.BigDecimalFormater.parseBigDecimal"
    printMethod="sample.BigDecimalFormater.printBigDecimal" />

这是我的格式化程序代码:

public class BigDecimalFormater {
    public static String printBigDecimal(BigDecimal value) {
        value.setScale(5);

        return value.toPlainString();
    }

    public static BigDecimal parseBigDecimal(String value) {
        return new BigDecimal(value);
    }
}

然后这个插件为我生成适配器

public class Adapter1 extends XmlAdapter<String, BigDecimal> {
    public BigDecimal unmarshal(String value) {
        return (sample.BigDecimalFormater.parseBigDecimal(value));
    }
    public String marshal(BigDecimal value) {
        return (sample.BigDecimalFormater.printBigDecimal(value));
    }
}

在生成的类BigDecimal字段有注解@XmlJavaTypeAdapter(Adapter1 .class),它解决了问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    相关资源
    最近更新 更多