Я работаю с несколькими API REST и несколько раз сталкивался с этим сценарием, и мне было интересно, каков наилучший подход к проектированию для доступа к вложенным данным, которые могут быть нулевыми.
Придуманный ниже пример демонстрирует объект, который содержит карту объектов, которые также содержат карту объектов и т. Д. Итак, есть MyClassA, у которого есть карта, которая содержит объекты MyClassB, которая содержит карту объектов MyClassC, которая содержиткарта объектов MyClassD.
Чтобы получить только атрибуты MyClassD, я должен просмотреть все карты классов, проверить, что результат не равен нулю, перед циклом просмотра карты полученных объектов и повторить, как показано в основном методе MyClassTests ниже.
В этом примере я использую строку json для представления данных, возвращаемых из вызова API.По этой причине я не могу применить какие-либо правила на картах, не добавляя нулевые значения на карту.Также я не использую ключ в примере, но это следует учитывать, так как это всего лишь надуманный пример.Я также намеренно использую корневой объект вместо использования ObjectMapper для пропуска вложения.
MyClassD:
public class MyClassD {
private String dataOfInterestA = null;
private String dataOfInterestB = null;
public MyClassD() {
}
public MyClassD(String dataOfInterestA, String dataOfInterestB) {
this.dataOfInterestA = dataOfInterestA;
this.dataOfInterestB = dataOfInterestB;
}
/**
* @return the dataOfInterestA
*/
public String getDataOfInterestA() {
return dataOfInterestA;
}
/**
* @param dataOfInterestA the dataOfInterestA to set
*/
public void setDataOfInterestA(String dataOfInterestA) {
this.dataOfInterestA = dataOfInterestA;
}
/**
* @return the dataOfInterestB
*/
public String getDataOfInterestB() {
return dataOfInterestB;
}
/**
* @param dataOfInterestB the dataOfInterestB to set
*/
public void setDataOfInterestB(String dataOfInterestB) {
this.dataOfInterestB = dataOfInterestB;
}
}
MyClassC:
import java.util.HashMap;
import java.util.Map;
public class MyClassC {
private Map<String, MyClassD> myClassDContainer = new HashMap<>();
/**
* @return the myClassDContainer
*/
public Map<String, MyClassD> getMyClassDContainer() {
return myClassDContainer;
}
/**
* @param myClassDContainer the myClassDContainer to set
*/
public void setMyClassDContainer(Map<String, MyClassD> myClassDContainer) {
this.myClassDContainer = myClassDContainer;
}
/**
* @param key
* @param myClassDContainerValue
*/
public void addMyClassDContainer(String key, MyClassD myClassDContainerValue) {
myClassDContainer.put(key, myClassDContainerValue);
}
}
MyClassB:
import java.util.HashMap;
import java.util.Map;
public class MyClassB {
private Map<String, MyClassC> myClassCContainer = new HashMap<>();
/**
* @return the myClassCContainer
*/
public Map<String, MyClassC> getMyClassCContainer() {
return myClassCContainer;
}
/**
* @param myClassCContainer the myClassCContainer to set
*/
public void setMyClassCContainer(Map<String, MyClassC> myClassCContainer) {
this.myClassCContainer = myClassCContainer;
}
/**
* @param key
* @param myClassCContainerValue
*/
public void addMyClassCContainer(String key, MyClassC myClassCContainerValue) {
myClassCContainer.put(key, myClassCContainerValue);
}
}
MyClassA:
import java.util.HashMap;
import java.util.Map;
public class MyClassA {
private Map<String, MyClassB> myClassBContainer = new HashMap<>();
/**
* @return the myClassBContainer
*/
public Map<String, MyClassB> getMyClassBContainer() {
return myClassBContainer;
}
/**
* @param myClassBContainer the myClassBContainer to set
*/
public void setMyClassBContainer(Map<String, MyClassB> myClassBContainer) {
this.myClassBContainer = myClassBContainer;
}
/**
* @param key
* @param myClassBContainerValue
*/
public void addMyClassBContainer(String key, MyClassB myClassBContainerValue) {
myClassBContainer.put(key, myClassBContainerValue);
}
}
MyClassTests:
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MyClassTests {
public static void main(String[] args) {
MyClassTests myClassTests = new MyClassTests();
MyClassA myClassAObject = myClassTests.getMyClassA();
// Get all the dataOfInterestA and store in list
List<String> dataOfInterestAList = new ArrayList<>();
if (myClassAObject != null && myClassAObject.getMyClassBContainer() != null) {
for (Entry<String, MyClassB> myClassBEntries: myClassAObject.getMyClassBContainer().entrySet()) {
MyClassB myClassB = myClassBEntries.getValue();
if (myClassB != null) {
for (Entry<String, MyClassC> myClassCEntries: myClassB.getMyClassCContainer().entrySet()) {
MyClassC myClassC = myClassCEntries.getValue();
if (myClassC != null) {
for (Entry<String, MyClassD> myClassDEntries: myClassC.getMyClassDContainer().entrySet()) {
MyClassD myClassD = myClassDEntries.getValue();
if (myClassD != null && myClassD.getDataOfInterestA() != null) {
dataOfInterestAList.add(myClassD.getDataOfInterestA());
}
}
}
}
}
}
}
}
public MyClassA getMyClassA() {
MyClassA myClassAObject = null;
String json = "{\"myClassBContainer\":{\"MyClassBKey\":{\"myClassCContainer\":{\"MyClassCKey\":{\"myClassDContainer\":{\"MyClassDKey\":{\"dataOfInterestA\":\"Data Of Interest A\",\"dataOfInterestB\":\"Data Of Interest B\"}}}}}}}";
// The formatted json from above looks like this:
/* {
"myClassBContainer": {
"MyClassBKey": {
"myClassCContainer": {
"MyClassCKey": {
"myClassDContainer": {
"MyClassDKey": {
"dataOfInterestA": "Data Of Interest A",
"dataOfInterestB": "Data Of Interest B"
}
}
}
}
}
}
}
*/
// Convert the json string to MyClassA object
try {
ObjectMapper objectMapper = new ObjectMapper();
myClassAObject = objectMapper.readValue(json, MyClassA.class);
} catch (IOException e) {
e.printStackTrace();
}
return myClassAObject;
}
}