【问题标题】:How to handle dynamic JSON value types when deserializing request with Spring?使用 Spring 反序列化请求时如何处理动态 JSON 值类型?
【发布时间】:2019-05-23 21:37:43
【问题描述】:

我正在尝试为我们公司使用 Spring 与他们的 API 交互的软件创建一个包装器。

目前,该软件的 API 返回一个平面 JSON 对象作为GET 请求的响应。我面临的问题取决于我们从中获取的某个字段中是否有数据将确定响应中的值是字符串还是 JSON 对象。

在 Spring 中创建模型时如何处理这种动态数据类型?

当只是处理数据时,如果该特定字段的数据为空,并且我在模型中将数据类型设置为 String,我可以将其反序列化为我的 result 对象。

当有此特定字段的数据时,反之亦然。我创建了一个名为 LinkValueObject 的自定义对象,它只包含两个属性 linkvalue。当我在该字段有数据时发出请求时,我再次能够正确反序列化它。我只是不确定如何动态处理这两种情况。

如果我弄错了术语,我深表歉意。

“assigned_to”中没有数据的响应示例:

{
    "result": {
        "name": "Bob Ross",
        "assigned_to": ""
    }
}

“assigned_to”中包含数据的响应示例:

{
    "result": {
        "name": "Bob Ross",
        "assigned_to": {
            "link": "https://mylink.com",
            "value": "qwerty123456"
        }
    }
}

我现在的模型如下所示:

// Using Lombok to auto-generate getters/setters

@Data
@NoArgsConstructor
@JsonInclude("JsonInclude.Include.NON_NULL")
public class Result {
    @JsonProperty("name")
    private String name;

    // This will handle if assigned_to returned as a JSON object
    // If assigned_to was empty, it would return as an empty string
    // and cause this to bomb out until the Data type was String again

    @JsonProperty("assigned_to")
    private LinkValueObject assignedTo;
}

【问题讨论】:

    标签: java json spring jackson


    【解决方案1】:

    您可以使用Declarative Stream Mapping (DSM) 流解析库轻松做到这一点。

    首先,您必须以 yaml 或 JSON 格式定义 JSON 数据与您的字段之间的映射。

    以下是映射定义:

    result:     
       type: object
       path: /result   
       fields:
         name: 
         assignedTo:
           type: object
           path: assigned_to
           filter: self.data.link!=null  # if link value is null filter assignedTo field                        fields:
              link:
              value:
    

    您要反序列化的 Java 类(与您的类相同):

    public class Result {
        public String name;
        public LinkValueObject  assignedTo;
    
        @Override
        public String toString() {
            return "Result [name=" + name + ", assignedTo=" + assignedTo + "]";
        }
        public static class LinkValueObject{
            public String link;
            public String value;
            @Override
            public String toString() {
                return "LinkValueObject [link=" + link + ", value=" + value + "]";
            }
        }
    }
    

    解析 JSON 的 Java 代码:

    DSM dsm=new DSMBuilder(new File("path/to/mapping.yaml")).create(Result.class);
    Result  result=  (Result)dsm.toObject(jsonData);
    

    System.out.println(object);

    这是输出:

    第一个输入:

    {
        "result": {
            "name": "Bob Ross",
            "assigned_to": ""
        }
    }
    

    第一个输出:

    Result [name=Bob Ross, assignedTo=null]
    

    第二个输入:

    {
        "result": {
            "name": "Bob Ross",
            "assigned_to": {
                "link": "https://mylink.com",
                "value": "qwerty123456"
            }
        }
    }
    

    第二次输出:

    Result [name=Bob Ross, assignedTo=LinkValueObject [link=https://mylink.com, value=qwerty123456]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多