【问题标题】:How to clone `com.fasterxml.jackson.core.JsonParser`如何克隆`com.fasterxml.jackson.core.JsonParser`
【发布时间】:2020-05-04 07:17:11
【问题描述】:

我需要解析同一个 json 流两次,一次是识别 json 流中数组的长度,然后是解析实体。但是,只有一个 JsonParser 实例可以开始。有没有办法可以克隆它或创建它的副本,因为一旦使用实例进行解析,它显然不能用于重新解析相同的 json 流。 提前致谢。

例子:


   static class ResultEntitiesContainer {
     List<ResultEntity> resultEntities;
     // getter and setters available
   }

    void parseEntities(JsonParser parser) {
      // Need to extract number of entities. 
      int count=0;
      ObjectMapper om = new ObjectMapper();
      JsonNode node = om.readTree(parser);
      node = node.get("resultEntities");
      if (node.isArray()) {
        count = node.size();
      }

      // Need to parse the entities in the json node
      ResultEntitiesContainer rec = om.readValue(parser, ResultEntitiesContainer.class);

    }

【问题讨论】:

  • 你能举个例子来展示一些代码吗?
  • 提供了一个例子。在这里,我需要使用相同的解析器实例,但是两次解析json流。
  • ResultEntitiesContainer 看起来如何?你能通过迭代ResultEntitiesContainer的字段来计算吗?
  • 只是一个容器类,没什么特别的。让我也补充一下。

标签: java json parsing fasterxml


【解决方案1】:

此答案旨在解决假设需要克隆 JsonParser 的问题。

com.fasterxml.jackson.core.JsonParser 是一个公共抽象类,它不提供clone 或类似方法。 抽象类可以通过 JsonParser.java 的作者无法控制的不同实现进行扩展。 同样,将 JsonParser 克隆为 void parseEntities(JsonParser parser); 的参数也不安全,因为 parseEntities 的作者无法确定使用了哪个实现以及是否可以克隆。

但是,如果您(作为parseEntities 的作者)确实可以控制使用的实现,那么克隆已知的实现是安全的(假设这是可能的)。 因此,如果您确实知道您的类将使用 JsonParser 的哪个特定实现(或多个实现),您可以尝试专门克隆这些已知实现。 例如。添加并实现一种或多种方法(根据需要),例如:

void parseEntities(MyJsonParser parser);

void parseEntities(MyOtherJsonParser parser);

那么就是克隆使用的JsonParser的具体实现的问题了。例如假设MyJsonParser 支持克隆以下可能是有效的。

void parseEntities(MyJsonParser 解析器){

MyJsonParser clonedParser=parser.clone();//取决于实现

...

}

【讨论】:

    【解决方案2】:

    据我所知,没有必要解析两次。只需将其解析为ResultEntitiesContainer 类型的对象并计算列表中的元素即可得到count。您可以更改方法parseEntities 如下:

    void parseEntities(JsonParser parser) {
       ObjectMapper om = new ObjectMapper();
    
       // Need to parse the entities in the json node
       ResultEntitiesContainer rec = om.readValue(parser, ResultEntitiesContainer.class);
       // Need to extract number of entities. 
       int count = rec.getResultEntities().size();   
    }
    

    或者,您可以从 json 节点解析为对象 ResultEntitiesContainer,如下所示:

    ResultEntitiesContainer rec = om.treeToValue(node, ResultEntitiesContainer.class);
    

    备注:

    • 请仔细检查ResultEntitiesContainer 是否应为static

    【讨论】:

    • 很抱歉,事实并非如此。我试图简化这里的例子,所以你提到的对于给出的例子是正确的。然而,真正的问题是能够克隆 JsonParser。
    • 我编辑了将 json 节点解析为对象而不是解析器的可能性的答案。您能否检查一下这是否适合您?
    猜你喜欢
    • 2010-10-17
    • 2012-05-27
    • 2012-06-17
    • 2010-12-30
    • 2015-01-26
    • 2011-03-31
    • 2011-08-20
    相关资源
    最近更新 更多