【问题标题】:Deserialise JSON payload to JsonNode with custom logic使用自定义逻辑将 JSON 有效负载反序列化为 JsonNode
【发布时间】:2021-11-09 06:33:29
【问题描述】:

我想将String 反序列化为JsonNode,同时尽可能将所有双精度数转换为整数。比如下面的代码

// str is = { "a": 1.0, "b": 0.5 }
var objectMapper = new ObjectMapper();
JsonNode n = objectMapper.readTree(str);

当前行为:n 的两个孩子都是DoubleNode 类型。

目标:对于n 的孩子,aIntNode 类型,bDoubleNode 类型。

我在这里看到了很多自定义反序列化器,但它们只适用于定义的 POJO,而不是任意的JsonNode 反序列化。非常感谢有关如何将字符串自定义为 JsonNode 反序列化的任何帮助。

【问题讨论】:

    标签: java json serialization jackson json-deserialization


    【解决方案1】:

    您可能希望预处理输入的 JSON 字符串并删除仅包含 0s 的小数部分以及小数点 .

    String str = "{ \"a\": \"1.0\", \"b\": 0.5, \"c\":\"0.01\", \"d\": 0.00}"
      .replaceAll("(\\d+)\\.0+(\\D)", "$1$2")); // check if fractional part contains only 0's
    
    System.out.println(str);
    

    这里"$1$2"指的是第一个(\\d+)(非空数字序列)和第二个(\\D)(任何非数字字符)匹配组,替换后应保留。

    输出:

    { "a": "1", "b": 0.5, "c":"0.01", "d": 0}
    

    那么ad就可以解析为整数了。

    【讨论】:

      【解决方案2】:

      如果您将JSON 反序列化为JsonNode,您可以覆盖JsonNodeFactory,它会创建带有数据的节点。示例:

      JsonMapper mapper = JsonMapper.builder()
              .nodeFactory(new JsonNodeFactory(true) {
                  @Override
                  public NumericNode numberNode(double v) {
                      if (v == (int) v) {
                          return super.numberNode((int) v);
                      }
                      if (v == (long) v) {
                          return super.numberNode((long) v);
                      }
                      return super.numberNode(v);
                  }
              })
              .build();
      

      如您所见,您可以定义将为给定值创建哪种类型的节点。

      类似的问题:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-19
        • 2022-11-15
        相关资源
        最近更新 更多