I downloaded some information in json format, but it looks different from what I am regularly used to. The basic structures consists of two objects: an array of arrays without keys and an array of objects with key:value pairs, indicating the "keys" for the first array and their type.
{
"datatable": {
"data": [
[
"2022-04-26",
118313,
0,
"QQQ",
null,
"BL6CD96",
"ARCAVA4600V8",
"XBUE",
"INVESCO QQQ TRUST SE1-CEDEAR",
"Invesco QQQ Trust Series 1",
"False",
"False"
],
[
"2022-04-26",
56360,
22669,
"QQQ",
"46090E103",
"BDQYP67",
"US46090E1038",
"XNAS",
"INVESCO QQQ TRUST SERIES 1",
"Invesco QQQ Trust Series 1",
"True",
"False"
],
[
"2022-04-26",
44307,
25533,
"IBM",
"459200101",
"2005973",
"US4592001014",
"XNYS",
"INTL BUSINESS MACHINES CORP",
"International Business Machines Corp",
"True",
"True"
]
],
"columns": [{
"name": "marketdate",
"type": "Date"
},
{
"name": "seckey",
"type": "Integer"
},
{
"name": "securityid",
"type": "Integer"
},
{
"name": "ticker",
"type": "text"
},
{
"name": "cusip",
"type": "text"
},
{
"name": "sedol",
"type": "text"
},
{
"name": "isin",
"type": "text"
},
{
"name": "mic",
"type": "text"
},
{
"name": "securityname",
"type": "text"
},
{
"name": "companyname",
"type": "text"
},
{
"name": "uslisted",
"type": "text"
},
{
"name": "innqgi",
"type": "text"
}
]
},
"meta": {
"next_cursor_id": null
}
}
Result I am trying to achieve:
{
"datatable": {
"data": [
[
"marketdate":"2022-04-26",
"seckey":118313,
"securityid":0,
"ticker":"QQQ",
"cusip":"null",
"sedol":"BL6CD96",
"isin":"ARCAVA4600V8",
"mic":"XBUE",
"securityname":"INVESCO QQQ TRUST SE1-CEDEAR",
"companyname":"Invesco QQQ Trust Series 1",
"uslisted":"False",
"innqgi":"False"
],
...
},
"meta": {
"next_cursor_id": null
}
}
How can I convert this into a regular key=value JSON OR How do I parse this in Java so that I have a POJO where the variable names = "colName"?
Thanks a lot! Nikhil
CodePudding user response:
You need to map column names from second array to values from first array using indexes. First let's create POJO structure.
public class DataObject {
private LocalDate marketDate;
private int secKey;
private int securityId;
private String ticker;
private String cusip;
private String sedol;
private String isin;
private String mic;
private String securityName;
private String companyName;
private String uslisted;
private String innqgi;
//getters and setters
}
Then:
public class DataWrapper {
private List<DataObject> data;
//getters setters
}
Response:
public class Response {
private DataWrapper datatable;
//getters setters
//omitting meta
}
Then create deserializer to map column names to corresponding values:
public class ResponseDeserializer extends StdDeserializer<Response> {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private final Map<String, BiConsumer<JsonNode, DataObject>> map = new HashMap<>();
public ResponseDeserializer() {
super(Response.class);
this.initMap();
}
private void initMap() {
map.put("marketdate", (jsonNode, dataObject) -> dataObject.setMarketDate(LocalDate.parse(jsonNode.asText(), FORMATTER)));
map.put("seckey", (jsonNode, dataObject) -> dataObject.setSecKey(jsonNode.asInt()));
map.put("cusip", (jsonNode, dataObject) -> dataObject.setCusip(jsonNode.asText()));
//do the same for rest
}
@Override
public Response deserialize(JsonParser parser, DeserializationContext context) throws IOException {
JsonNode root = parser.getCodec().readTree(parser);
ArrayNode dataArray = (ArrayNode) root.get("datatable").get("data");
ArrayNode columnsArray = (ArrayNode) root.get("datatable").get("columns");
List<DataObject> objects = new ArrayList<>(dataArray.size());
for (int index = 0; index < dataArray.size(); index ) {
ArrayNode data = (ArrayNode) dataArray.get(index);
DataObject dataObject = new DataObject();
for (int dadaIndex = 0; dadaIndex < data.size(); dadaIndex ) {
JsonNode node = data.get(dadaIndex);
String columnName = columnsArray.get(dadaIndex).get("name").asText();
this.map.getOrDefault(columnName, (jsonNode, dataObject1) -> {}).accept(node, dataObject);
}
objects.add(dataObject);
}
DataWrapper wrapper = new DataWrapper();
wrapper.setData(objects);
Response response = new Response();
response.setDatatable(wrapper);
return response;
}
}
Here i am using a Map
to map column name to operation setting the value, but you could do it with reflection as well, for example.
A serializer to parse local date to the same format as in input:
public class LocalDateSerializer extends StdSerializer<LocalDate> {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public LocalDateSerializer() {
super(LocalDate.class);
}
@Override
public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeString(FORMATTER.format(value));
}
}
Register serializers/deserializers and test result:
public class Main {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Response.class, new ResponseDeserializer());
module.addSerializer(LocalDate.class, new LocalDateSerializer());
mapper.registerModule(module);
Response response = mapper.readValue(inputJson, Response.class);
String json = mapper.writeValueAsString(response);
System.out.println(json);
}
}
CodePudding user response:
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
class HashMapExample {
private static HashMap<String, Integer> bigHashMap;
public static void main(String[] args) {
try {
JSONObject jsonObject = getJsonFromSource();
// Get datatable object from JSONObject
JSONObject dataTable = (JSONObject) jsonObject.get("datatable");
if (dataTable != null) {
// Get JSONArray from JSONObject datatable
JSONArray data = dataTable.getJSONArray("data");
JSONArray columns = dataTable.getJSONArray("columns");
mapToKeyValuePair(data, columns); // Map key to value
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
private static void mapToKeyValuePair(final JSONArray dataArray, final JSONArray columnsArray) {
// Check for equal lengths
if ((dataArray != null) && (columnsArray != null)) {
ArrayList<String> fieldNames = new ArrayList<>(); // ArrayList with field names
ArrayList<String> dataValuesArrays = new ArrayList<>(); // ArrayList with the data values
ArrayList<HashMap> wholeFinalArray = new ArrayList<>(); // The whole array with key pair value
// Loop to get a JSONObject with all the column names
for (int i = 0; i < columnsArray.length(); i ) {
JSONObject jsonObjectColumn = (JSONObject) columnsArray.get(i); // Get JSONObject with column names
fieldNames.add(jsonObjectColumn.get("name").toString()); // Get fieldNames from JSONObject above
}
for (int i = 0; i < dataArray.length(); i ) {
JSONArray jsonArrayData = (JSONArray) dataArray.get(i); // Get JSONArray with data
dataValuesArrays.add(jsonArrayData.toString()); // Add the data to an ArrayList
}
// Loop through the data values combined arrays
for (String dataValuesArray : dataValuesArrays) {
JSONArray singleDataArray = new JSONArray(dataValuesArray); // Get single data array
for (int a = 0; a < singleDataArray.length(); a ) {
HashMap<String, String> item = new HashMap<>();
item.put(fieldNames.get(a), singleDataArray.get(a).toString());
wholeFinalArray.add(item);
}
}
System.out.println(wholeFinalArray);
}
}
private static JSONObject getJsonFromSource() {
String jsonResponse = "{'datatable':{'data': [['2022-04-26', 118313, 0, 'QQQ', null, "
"'BL6CD96', "
"'ARCAVA4600V8', 'XBUE', 'INVESCO QQQ TRUST SE1-CEDEAR', 'Invesco QQQ Trust Series 1', 'False', 'False'],['2022-04-26', 56360, 22669, 'QQQ', '46090E103', 'BDQYP67', 'US46090E1038', 'XNAS', 'INVESCO QQQ TRUST SERIES 1', 'Invesco QQQ Trust Series 1', 'True', 'False'],['2022-04-26', 44307, 25533, 'IBM', '459200101', '2005973', 'US4592001014', 'XNYS', 'INTL BUSINESS MACHINES CORP', 'International Business Machines Corp', 'True', 'True']],'columns': [{'name':'marketdate', 'type':'Date'},{'name':'seckey', 'type':'Integer'},{'name':'securityid', 'type':'Integer'},{'name':'ticker', 'type':'text'},{'name':'cusip', 'type':'text'},{'name':'sedol', 'type':'text'},{'name':'isin', 'type':'text'},{'name':'mic', 'type':'text'},{'name':'securityname', 'type':'text'},{'name':'companyname', 'type':'text'},{'name':'uslisted', 'type':'text'},{'name':'innqgi', 'type':'text'}]}, 'meta':{'next_cursor_id':null}}";
return new JSONObject(jsonResponse);
}
}