为十进制逻辑类型和avro模式的字节类型创建json表示形式

时间:2019-09-18 14:49:21

标签: scala avro event-bus avro-tools

我正在尝试根据avro模式下的JSON字符串创建十进制值。 https://avro.apache.org/docs/1.8.2/spec.html#Logical+Types

{
 "name": "score",
 "type": "bytes",
 "logicalType": "decimal",
 "precision": 10,
 "scale": 5
 }

"score":3.4,

我正在例外

Caused by: org.apache.avro.AvroTypeException: Expected bytes. Got VALUE_NUMBER_FLOAT.

如果我输入“ \ u0000”而不是3.4,那么它可以工作,但这是0的表示形式,我将如何获得3.4的表示形式? 目前,我正在创建硬编码的JSON字符串,但是将来我必须将输出转换为Decimal,如何在scala中做到这一点。

有什么方法可以将值转换为十进制逻辑格式?

1 个答案:

答案 0 :(得分:2)

Java代码:

byte[] score = new BigDecimal("3.40000").unscaledValue().tobyteArray();
for (byte b : score) {​
    System.out.println(String.format("\\u%04x", b));
}

将打印出以下内容:

\u00fa
\u00cf
\u00e0

然后您需要这样写json得分值:

"score":"\u00fa\u00cf\u00e0",

它应该转换为3.40000。 3. 40000 的原因是,您架构中的“ scale”值为5。如果scale的值为2,那么我们将拥有新的BigDecimal(“ 3.40”)

用于将BigDecimal转换为json的scala函数,以便avro可以理解

def toJsonString(value: java.math.BigDecimal): String = {
    val bytes = value.unscaledValue().toByteArray
    bytes
      .map(_.formatted("\\u%04x"))
      .mkString
}