Как я должен сопоставить тело моего запроса с другим объектом, сохраняя при этом те же дочерние отношения?

#java #json #arraylist #depth-first-search #breadth-first-search

#java #json #arraylist #поиск в глубину #поиск в ширину

Вопрос:

У меня есть тело запроса с этим классом модели:

 public class IvrRequest {
    int age;
    String name;
    String address;
    List<IvrRequest> children;
}
  

Я хочу сопоставить это с другой моделью класса, например:

 public class IvrMapper {
    int id;
    String name;
    List<IvrMapper> resourceElements;
}
  

Какой подход я должен использовать для этого?

Пример:-

 {
    "age":16,
    "name":"Rohit",
    "address":"adgsgdsdfgsdfgsf",
    "children":[
    {
        "age":16,
        "name":"Rohit",
        "address":"adgsgdsdfgsdfgsf",
        "children":[{
            "age":16,
            "name":"Rohit",
            "address":"adgsgdsdfgsdfgsf"                
        }]
    },
    {
        "age":45,
        "name":"Singh",
        "address":"45afasdfas54df6asdf",
        "children":[{
            "age":55,
            "name":"nitin",
            "address":"@%^%@#^Ghagdhasdhg"              
        }]
    }]
}
  

Это пример для тела запроса.

Комментарии:

1. В чем проблема с повторением List<IvrRequest> и для каждого элемента созданием другого объекта?

2. Я не могу изменить определение классов

3. Есть ли способ, которым это можно сделать с помощью DFS?

4. У вас есть два POJO класса, которые вы не можете изменить, и вы хотите сопоставить одинаковую JSON полезную нагрузку двум из них, я прав?

5. ДА… но поля различны в обоих классах POJO

Ответ №1:

Вы не указали, какую библиотеку вы используете, поэтому я предлагаю использовать, Jackson которая позволяет быстро и легко выполнять десериализацию из JSON в Java модель и из одной POJO в другую. Если вы не можете изменить класс или класс принадлежит 3-rd party библиотеке, вы всегда можете использовать MixIn функцию. Приведенный ниже пример показывает, как:

  • Десериализовать JSON в IvrRequest
  • Десериализовать JSON в IvrMapper
  • Преобразовать IvrRequest в IvrMapper

Простое приложение:

 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.util.List;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        mapper.addMixIn(IvrMapper.class, IvrMapperMixIn.class);

        System.out.println("Parse IvrRequest model: ");
        IvrRequest ivrRequest = mapper.readValue(jsonFile, IvrRequest.class);
        System.out.println(ivrRequest);

        System.out.println("Parse IvrMapper model: ");
        System.out.println(mapper.readValue(jsonFile, IvrMapper.class));

        System.out.println("Convert IvrRequest to IvrMapper");
        System.out.println(mapper.convertValue(ivrRequest, IvrMapper.class));
    }
}

@JsonIgnoreProperties(ignoreUnknown = true)
interface IvrMapperMixIn {

    @JsonProperty("age")
    int getId();

    @JsonProperty("children")
    List<IvrMapper> getResourceElements();
}

class IvrRequest {

    private int age;
    private String name;
    private String address;
    private List<IvrRequest> children;

    // getters, setters, toString
}

class IvrMapper {
    private int id;
    private String name;
    private List<IvrMapper> resourceElements;

    // getters, setters, toString
}
  

Приведенные выше отпечатки приложений:

 Parse IvrRequest model: 
age=16, name='Rohit', address='adgsgdsdfgsdfgsf'
 children=
    age=16, name='Rohit', address='adgsgdsdfgsdfgsf'
 children=
    age=16, name='Rohit', address='adgsgdsdfgsdfgsf'

    age=45, name='Singh', address='45afasdfas54df6asdf'
 children=
    age=55, name='nitin', address='@%^%@#^Ghagdhasdhg'


Parse IvrMapper model: 
id=16, name='Rohit'
 resourceElements=
    id=16, name='Rohit'
 resourceElements=
    id=16, name='Rohit'

    id=45, name='Singh'
 resourceElements=
    id=55, name='nitin'


Convert IvrRequest to IvrMapper
id=16, name='Rohit'
 resourceElements=
    id=16, name='Rohit'
 resourceElements=
    id=16, name='Rohit'

    id=45, name='Singh'
 resourceElements=
    id=55, name='nitin'
  

Комментарии:

1. Большое спасибо, чувак….. Это был отличный способ сделать это, но могу ли я сделать это без использования какой-либо библиотеки и ручного синтаксического анализа с использованием DFS или рекурсии?

2. @rohitsingh, конечно, вы можете сделать это вручную, используя рекурсию, но я не вижу никаких причин делать это таким образом. Не могли бы вы объяснить, почему вы хотите сделать это вручную?

3. На самом деле мне не разрешено использовать какую-либо внешнюю библиотеку или метод …. просто хочу использовать какой-то алгоритм

4. Это всего лишь ссылка, реальная проблема намного сложнее, и эта функция не будет работать над этим one….so нужно использовать какой-то алгоритм

5. @rohitsingh, итак, каков ваш JSON файл ввода? Или IvrRequest возражать? Что вы подразумеваете под «мне не разрешено использовать какую-либо внешнюю библиотеку» — можете ли вы использовать только внутренние JDK классы? У вас есть список разрешенных библиотек? Я думаю, вам следует создать новый вопрос со ссылкой на этот и явно указать, что такое ввод и вывод и какие классы вы можете использовать.