当前位置: 首页 > 知识库问答 >
问题:

Jackson:如何反序列化JSON数组中的空元素

祖利
2023-03-14

编辑:应你们中一些人的要求,我发布了我的真实数据结构和类。我没能让你更容易理解这个问题。

我在解决JacksonnullJSON数组元素时遇到问题,最终出现异常,我将在本文后面报告。

我有一个来自第三方提供商的冗长的JSON字符串

[
  null,
  null,
  [
    {
      "t" : {
        "id" : 0,
        "it" : "Attuazione"
      },
      "c" : "DM.10.0.2",
      "l" : "Macro 2",
      "v0" : 0,
      "scid" : "1",
      "m" : "10",
      "sam" : 0,
      "v1" : 100,
      "smcm" : true,
      "w" : "OD.10.4",
      "st" : {
        "auto_formula" : {
          "ia" : "($x > 0 ? 1 : 0)",
          "id" : "($x > 0 ? 1 : 0)",
          "bit" : "($x > 0 ? 1 : 0)",
          "oa" : "($x > 0 ? 1 : 0)",
          "od" : "($x > 0 ? 1 : 0)",
          "dm" : "($x > 0 ? 1 : 0)"
        },
        "id" : 0,
        "css_rule" : "containerTypeOnOff",
        "default_measure_unit" : null,
        "it" : "On \/ Off",
        "widget" : {
          "id" : 0,
          "caption" : {
            "it" : "Etichetta di testo"
          }
        }
      }
    }
  ],
  null,
  null,
  null,
  null,
  null
]

我的Java合奏如下。

这是最外层的容器:

public class TinyMap {
    ArrayList<TinyMapModule> modules;

    public TinyMap() { ...  }

    public ArrayList<TinyMapModule> getModules() { ... }

    /**
     * @param modules the modules to set
     */
    @SuppressWarnings("unchecked")
    public void setModules(ArrayList<TinyMapModule> modules) { ... }

    public void appendNewMacro(TinyMapModule m) { ... }

}

这是第一级容器:

public class TinyMapModule {
    private ArrayList<TinyMapMacro> macros;

    /**
     * C'tor 
     */
    public TinyMapModule() { ... }

    /**
     * @return ArrayList<TinyMapMacro> 
     */
    public ArrayList<TinyMapMacro> getMacros() { ... }

    /**
     * @param macros the macros to set
     */
    @SuppressWarnings("unchecked")
    public void setMacros(ArrayList<TinyMapMacro> macros) { ... }

}

这是最里面的层次:

public class TinyMapMacro {
    private String c; 
    private String l;
    private String m;
    private MacroType t;
    private String w;

    private static Logger logger;

    static {
        logger = Logger.getLogger(TinyMapMacro.class);
        DOMConfigurator.configure("log4j.xml");
    }

    /**
     * C'tor 
     */
    public TinyMapMacro() { ... }

    public static class MacroType {
        private int id;
        private String it; // Italian

        public int getId() { ... }
        public void setId(int id) { ... }
        public String getIt() { ... }
        public void setIt(String it) { ... }
    }

    public String getC() { ... }

    public void setC(String c) { ... }

    public String getL() { ... }

    public void setL(String l) { ... }

    public String getM() { ... }

    public void setM(String m) { ... }

    public MacroType getT() { ... }

    public void setT(MacroType t) { ... }

    public String getW() { ... }

    public void setW(String w) { ... }

    public int getTypeId() { ... }

    public String getLocalizedTypeString() { ... }

}

最后,这是我的反序列化代码:

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
ObjectReader reader = mapper.reader(TinyMapModule.class);
try {
    logger.info("Instantiating ObjectMapper");
    TinyMap tm = new TinyMap();
    tm.buildTinyMap(reader.readValues(jsonString.replaceAll("null", "[{\"name\":\"\"}]")));
    for (int i = 0; i < tm.getModules().size(); i++) {
        if (tm.getModules().get(i) == null) 
            continue;
        for (int j = 0; j < tm.getModules().get(i).getMacros().size(); j++) {
            if (tm.getModules().get(i).getMacros().get(j) == null) 
                continue;
            System.out.println(String.format("c: %s", tm.getModules().get(i).getMacros().get(i).getC()));
            System.out.println(String.format("l: %s", tm.getModules().get(i).getMacros().get(i).getL()));
            System.out.println(String.format("m: %s", tm.getModules().get(i).getMacros().get(i).getM()));
            System.out.println(String.format("t.id: %d", tm.getModules().get(i).getMacros().get(i).getTypeId()));
            System.out.println(String.format("t.it: %s", tm.getModules().get(i).getMacros().get(i).getLocalizedTypeString()));
            System.out.println(String.format("w: %s", tm.getModules().get(i).getMacros().get(i).getW()));
        }
    }
    logger.info("Execution terminated");
} 
... 

在极端综合法中,我试图将问题概括如下:

  1. TinyMap 类有一个模块成员,它是一个微小地图对象的数组列表
  2. 微小映射模型类有一个宏成员,它是微小映射对象的数组列表
  3. TinyMapMacro 类映射具有我严格需要的唯一属性的对象。

现在,当我尝试将上面的 JSON 字符串反序列化到我的对象中时,我得到一个异常,告诉我 JSON 不能反序列化:

Exception in thread "main" com.fasterxml.jackson.databind.RuntimeJsonMappingException: Can not deserialize instance of it.asystelsrl.hcsbridge.communication.TinyMapModule out of START_ARRAY token
 at [Source: java.io.StringReader@3c50507; line: 1, column: 2]
    at com.fasterxml.jackson.databind.MappingIterator.next(MappingIterator.java:122)
    at it.asystelsrl.hcsbridge.communication.TinyMap.buildTinyMap(TinyMap.java:47)
    at it.asystelsrl.hcsbridge.tests.TestTinyMap.main(TestTinyMap.java:69)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of it.asystelsrl.hcsbridge.communication.TinyMapModule out of START_ARRAY token
 at [Source: java.io.StringReader@3c50507; line: 1, column: 2]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:599)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:593)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromArray(BeanDeserializer.java:531)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:141)
    at com.fasterxml.jackson.databind.MappingIterator.nextValue(MappingIterator.java:188)
    at com.fasterxml.jackson.databind.MappingIterator.next(MappingIterator.java:120)
    ... 2 more

我已经阅读了很多关于Jackson注释、自定义反序列化器等的内容。但我想到的唯一解决方案似乎是从< code>ArrayList转换< code>TinyMap.modules成员

通过这种选择(若可行的话,因为我还并没有测试它),我将失去TinyMap的语义值。modules成员,我不会被迫这样做。

有没有其他方法可以解决空元素问题?

编辑:

重要的是,我可以保留这个结构中非空对象的顺序位置,所以我至少应该用可用作占位符的东西替换空元素。

共有2个答案

步胜
2023-03-14

您仍然只在示例 JSON 中显示 “比斯” 属性,而不是完整的“我的容器”对象。您的错误听起来像是它实际上试图将给定的 JSON 解析为我的容器

为了确保安全,你能发布完整的JSON对象和你的反序列化代码吗?

杰克逊理解零POJO就好了。

凌智
2023-03-14

这里的问题是,我用杰克逊做了很多混乱。

阅读程序员布鲁斯的这篇文章,我开始理解它。

正如StaxMan在评论中所建议的那样,我试图将一个收藏反序列化为其他东西。

感谢ProgrammerBruce的有用而清晰的文章。

 类似资料:
  • 我正在使用Jackson 2库,我正在尝试反序列化JSON响应,如下所示: 出于某些原因,我的员工数组中有一个空元素。在反序列化过程中,是否可以丢弃该元素并避免反序列化它?目前,我的代码将空员工反序列化为具有空字段的员工 POJO 类。 我的代码如下所示: 附言。我不能碰JSON响应。它就是这样…

  • 我正在阅读Facebook的洞察,并试图让Jackson将JSON映射到Object。如果所有的数据都不是空的,我就会让它正常工作。但是我在尝试反序列化键值的空数组时遇到了问题。即使尝试了这篇文章:如何防止Map内部的null值和bean内部的null字段通过Jackson序列化,也没有解决问题:( 这是JSON: 我的代码段如下: 全堆栈跟踪:

  • 我收到来自第3方服务提供商的JSON响应,其中包含一系列对象。当我尝试使用Jackson api反序列化JSON时。我收到以下异常 我的回答是 我的POJO课是这样的 我正在尝试使用以下代码反序列化JSON 如果我试着去做 它在BEGIN_对象本身失败。 如何使用数组读取和反序列化JSON。我应该编写自己的反序列化器吗? 编辑如果我使用JSON字符串而不是流,那么我就能够取回所有Java对象。但为

  • 我似乎很专注于如何去硬化数组数组。我对这些工具很陌生,无法处理JSON文件,我能够去硬化来自国家(https://restcountries.eu/rest/v2/all)的REST应用编程接口的JSON,但我现在正试图从开放天空应用编程接口(https://opensky-network.org/api/states/all?lamin=45.8389 我有这门课: 有能手和二传手 还有这个:

  • 我将用混合对象序列化/反序列化对象数组。因此,我创建了一个MyList类,并用字符串、int和date对象填充items数组。与jackson的连载效果很好。json字符串如下所示: 但是在反序列化时,json字符串date被解析为整数。因此,我创建了一个自己的类MyDate,将日期包装为字段名为“date”的json对象。新的结果是: 现在结果是LinkedHashMap。 以下是我的代码示例:

  • 问题内容: 我和Jackson有一个问题,我认为应该很容易解决,但是这真使我丧命。 假设我有一个看起来像这样的Java POJO类(假设对我来说是Getters和Setters): 我想将看起来像这样的JSON反序列化为User对象: 杰克逊给了我一些问题,因为用户不是JSON中的第一级对象。我显然可以制作一个具有单个User对象的UserWrapper类,然后使用该对象反序列化,但是我知道必须有