【问题标题】:How to parse field that may be a string and may be an array with Jackson如何解析可能是字符串并且可能是杰克逊数组的字段
【发布时间】:2020-05-22 15:21:33
【问题描述】:

我是 java 和 objectMapper 的新手。我正在尝试解析一个键可能有两种类型的 json 字段,它可以是字符串或数组。

例子:

{
  "addresses": [],
  "full_name": [
    "test name_1",
    "test name_2"
  ],
}

{
{
  "addresses": [],
  "full_name": "test name_3",
}
}

类示例:


@JsonIgnoreProperties(ignoreUnknown = true)
@Data -> lombok.Data
public class Document {

    private List<String> addresses;

    @JsonProperty("full_name")
    private String fullName;
}

我使用 objectMapper 反序列化 json,当 'full_name' 字段有字符串但到达数组时反序列化失败。

这个想法是,当到达一个字符串时,将值放入属性中,但当到达数组时,将 de 数组元素连接为字符串 (String.join(",", value))

可以在类方法中应用自定义反序列化吗?例如 setFullName() (使用 lombok.Data)

我在这个网站上看到了其他例子,但没有用。

谢谢大家

【问题讨论】:

    标签: java jackson objectmapper


    【解决方案1】:

    从杰克逊 2.6 开始,您可以使用JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY

    @JsonProperty("full_name")
    @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    private String[] fullName;
    

    【讨论】:

      【解决方案2】:

      详细说明@Deadpool 答案,您可以使用接受数组然后将其加入字符串的setter:

      @JsonProperty("full_name")
      @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
      void setFullName(String[] name)
      {
          this.fullName = String.join(",", name);
      }
      

      【讨论】:

        【解决方案3】:

        两个答案都很棒。我只想提一下自定义反序列化器。

        您可以轻松地从 StdDeserializer&lt;Document&gt; 扩展并覆盖 deserialize 方法:

        public class DocumentDeserializer extends StdDeserializer<Document> {
        
            @Override
            public Document deserialize(JsonParser p, DeserializationContext ctxt, Document value) throws IOException {
        
                JsonNode root = p.getCodec().readTree(p);
                JsonNode node = root.get("full_name");
                if(node.isArray()) {
                    //get array data from node iterator then join as String and 
                    //call setFirstName
                }
                return value;
            }
        }
        

        然后不要忘记致电ObjectMapper 中的registerModule 注册您的deserializer

        【讨论】:

        • 我会尝试这样做,但使用之前的答案,代码可以正常工作,谢谢您的时间
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多