Как обрабатывать динамические типы значений JSON при десериализации запроса с помощью Spring? - PullRequest
0 голосов
/ 24 мая 2019

Я пытаюсь создать оболочку для программного обеспечения, которое наша компания использует для взаимодействия со своим API с помощью Spring.

В настоящий момент API этого программного обеспечения возвращает плоский объект JSON в ответ на запрос GET. Проблема, с которой я сталкиваюсь, зависит от того, есть ли данные в одном из полей, из которых мы получаем данные, и будет определять, является ли значение в ответе объектом String или JSON.

Как справиться с этим динамическим типом данных при создании модели в Spring?

Когда я просто играю с данными, если данные для этого конкретного поля пусты, и в моей модели установлен тип данных String, я могу десериализовать это для моего объекта result.

И наоборот, когда есть данные для этого конкретного поля. Я создаю пользовательский объект с именем LinkValueObject, который просто содержит 2 атрибута link и value. Когда я делаю запрос, когда есть данные для этого поля, я снова могу десериализовать это правильно. Я просто не уверен, как динамически обрабатывать оба случая.

Приношу свои извинения за неправильную терминологию.

Пример ответа без данных в "assign_to":

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

Пример ответа с данными в "assign_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;
}

1 Ответ

0 голосов
/ 24 мая 2019

Вы можете использовать Декларативное потоковое сопоставление (DSM) библиотека анализа потока, чтобы легко сделать это.

Прежде всего, вы должны определить отображение между данными JSON и вашими полями в формате yaml или 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 + "]";
        }
    }
}

Java-код для анализа JSON:

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

System.out.println (объект);

Вот результаты:

Первый ввод:

{
    "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]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...