Нужно распарсить такой сложный JSON:
{
"receiveData": {
"iBusData": {
"requestUID": "44bd8a65-d128-48a4-b070-5f90fc5a7674",
"messageKind": "PublishedData",
"sender": "ST-DELLIN-307",
"senderDateTime": "2018-11-07T10:43:41",
"typeName": "typeInvoice",
"currentSenderApplication": "GP",
"objectUID": "322dd3cf-ae4c-4fcc-b785-c2b7698b85b4",
"data": {
"invoice": {
"uid": "322dd3cf-ae4c-4fcc-b785-c2b7698b85b4",
"presentation": "Test_Invoice",
"date": "2018-11-07T10:43:42",
"number": "Test_Invoice",
"marked": false,
"posted": false,
"senderCityUID": "d645a316-564b-4f38-b0b6-4a1541eb70ce",
"receiverTerminalUID": "d8bd5e84-c604-4125-aa2b-55a6f23f9e85",
"receiverCityUID": "e94042e3-d88e-4097-9349-878989ad28c1",
"cargoUID": "21e8eb95-b0aa-477c-b756-e7304921a3d2",
"amount": 1,
"amountExtraLarge": 1,
"netWeight": 1,
"netWeightExtraLarge": 1,
"grossWeight": 1,
"netVolume": 1,
"netVolumeExtraLarge": 1,
"grossVolume": 1,
"declaredValue": 1,
"contractorSenderUID": "e5a4a6ff-2a74-46ac-9e98-7a6cab5dc388",
"contractorReceiverUID": "993fb6ed-70cc-4b47-87b6-7e0a82affdb2",
"contractorPayerUID": "7b60e946-d327-44d4-a0a5-2ebf5ef1ad1c",
"contractorSenderIssueUID": "ef0453ff-c8df-4fd1-95ab-7943baee9c71",
"contractorReceiverIssueUID": "aaf30c1d-8d8b-4cf9-a1a1-04d8b3d0eab3",
"actualReceiver": "Test_Invoice",
"freightInKops": 1,
"deliveryTimeInsuranceSum": 1,
"terminalUID": "47e1481c-1191-49ba-ad11-aceb46284fca",
"cargoInsuranceSum": 1,
"personalID": null,
"senderCityName": "Test_Invoice",
"senderCityKLADR": "Test_Invoice",
"receiverCityName": "Test_Invoice",
"receiverCityKLADR": "Test_Invoice",
"transportationCostOnReceiving": 1,
"transportationCostOnIssuing": 1,
"invoiceUID": "35faff4b-85e3-428b-ab09-4462f118a585"
}
}
}
}
}
Сложность в том, что эти данные надо обработать так:
data
и записать его в поле объекта Java.Как это можно сделать при помощи библиотек десериализации типа Jackson или Gson? В интернете много примеров того, как вложенный json преобразуется в объект с такой же вложенностью. Но мне нужны более сложные операции.
Воссоздаем аналогичную структуру JSON в POJO классе, и уже парсим респонс так
MyPojo string = new Gson().fromJson(jsonStr, MyPojo.class);
Преобразование POJO класса обратно
String jsonStr = new Gson().toJson(myPojo);
По "не вложенности" - как вариант, создать доп. класс с функцией конвертирования полученного объекта в новый без вложенности и обратно (mapstruct в этом поможет), а там уже и хеши и что уже захотите с ним сделать.
(Jackson) Вам может помочь аннотация @JsonDeserialize(using = DataDeserializer.class), где DataDeserializer это десериализатор, в котором можно прописать любую логику конвертации. Как пример создаём генерик класс, который лазит по всем классам и собирает самые нижние поля.
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.time.LocalDateTime;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
public class CustomDeserializer<T> extends StdDeserializer<T> {
protected CustomDeserializer() {
super(LocalDateTime.class);
}
@Override
public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
try {
final T instance = ((Class<
T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0])
.newInstance();
final TreeNode treeNode = jsonParser.readValueAsTree();
parseNode(treeNode, instance);
return instance;
} catch (NoSuchFieldException | IllegalAccessException | InstantiationException e) {
throw new RuntimeException(e);
}
}
private void parseNode(final TreeNode treeNode, final T instance)
throws IOException, NoSuchFieldException, IllegalAccessException {
final Iterator<String> names = treeNode.fieldNames();
while (names.hasNext()) {
final String nodeName = names.next();
final TreeNode nextNode = treeNode.get(nodeName);
if (nextNode.isObject()) {
parseNode(nextNode, instance);
} else {
final String value = nextNode.toString();
final Field declaredField = Data.class.getDeclaredField(nodeName);
final Class<?> fieldType = declaredField.getType();
final ObjectMapper objectMapper = new ObjectMapper();
final Object deserializedValue = objectMapper.readValue(value, fieldType);
declaredField.setAccessible(true);
declaredField.set(instance, deserializedValue);
}
}
}
}
Дальше создаём наследника c генериком нужного нам типа:
public class DataDeserializer extends CustomDeserializer<Data> {}
Затем помечаем наш класс аннотацией:
@JsonDeserialize(using = DataDeserializer.class)
public class Data {...
Ну и парсим:
final ObjectMapper objectMapper = new ObjectMapper();
try {
final Data data = objectMapper.readValue("JSON_VALUE", Data.class);
} catch (IOException e) {
...
}
C простыми полями должно сработать. Теоретически, можно отфильтровать объекты, поля которых забирать наверх не нужно.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Нужно,что бы при выборе изображения оно перемещалось в корневую папку программы, как это можно реализовать ? Пытался через Filescopy и Files
У меня имееться два подобных класса LowPathFilter и HighPathFilter
Необходимо получить информацию о курсе валют , на сайте банка есть api в формате json нужно как получить себе в приложениеhttp://www
Реализую пример из книги "Spring 4 для профессионалов" из главы "Использование Hibernate в Spring"Использую БД H2