Im trying to make a JAVA application that makes a json file with the data that i send, but when i send new data, the last data the data is just replaced
the first method called
az.addUser("John", "10", "star");
the JSON
{
"user" : {
"name": "john",
"score": "10",
"type": "star"
}
}
second method called
az.addUser("Kevin", "20", "energy");
The JSON Expected
{
"user" : {
"name": "john",
"score": "10",
"type": "star"
}
"user" : {
"name" = "Kevin",
"score" = "20",
"type" = "energy"
}
}
the REAL JSON
{
"user" : {
"name" = "Kevin",
"score" = "20",
"type" = "Energy"
}
}
The Method
public void addUser(String name, String score, String type){
FileWriter wf = new FileWriter("exit.json");
JSONObject json;
JSONObject jsonInternal = new JSONObject();
jsonInternal.put("name", name);
jsonInternal.put("score", score);
jsonInternal.put("type", type);
json = new JSONObject();
json.put("user", jsonInternal);
wf.write(json.toJSONString());
wf.close();
}
You need to write a JSON array, not a JSON object. The code below is strictly pseudocode, as I do not know which library JSONObject comes from.
import java.io.FileWriter;
import java.io.IOException;
public class UserListWriter {
private String filename;
private JSONArray usersJson;
public UserListWriter(String filename) {
this.filename = filename;
this.usersJson = new JSONArray();
}
public UserListWriter addUser(String name, int score, String type) {
JSONObject userJson = new JSONObject();
userJson.put("name", name);
userJson.put("score", score);
userJson.put("type", type);
usersJson.put(userJson);
return this;
}
public UserListWriter write() throws IOException {
FileWriter wf = new FileWriter(this.filename);
wf.write(usersJson.toJSONString());
wf.close();
return this;
}
public static void main(String[] args) {
try {
new UserListWriter("exit.json")
.addUser("John", 10, "star")
.addUser("Kevin", 20, "energy")
.write();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Theoretical output:
[{
"name": "John",
"score": 10,
"type": "star"
}, {
"name": "Kevin",
"score": 20,
"type": "energy"
}]
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
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);
}
}
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);
}
}
I need to parse a string that contains data of JSON file into a JSONObject and iterate over it's content to get it's keys and values for further treatement after. I'am stuck at parsing the content of a file after transforming it to a string. I tried to user parse() , quote() but it seems i'am missing a detail and i'am making a major mistake.
This is a snippet of the json file i treat :
{
{
"id":0,
"name": "project1",
"couverage": "100",
"completness": "44.8",
"consistency": "46",
}
{
"id":1,
"name": "project2",
"couverage": "100",
"completness": "44.8",
"consistency": "46",
}
{
"id":2,
"name": "project3",
"couverage": "100",
"completness": "44.8",
"consistency": "46",
}
}
and this is the code i developed
public void readfromJsonFile(File jsonFile, long readTimeStamp) {
logger.info("Read from JSON file: {}", jsonFile.getName());
try{
//Read File Content
String content = new String(Files.readAllBytes(jsonFile.toPath()));
JSONParser jsonParser = new JSONParser(content);
JSONObject obj = (JSONObject) jsonParser.parse();
JSONArray key = obj.names();
for (int i = 0; i < key.length (); ++i) {
String keys = key.getString(i);
System.out.println(keys);
String value = obj.getString (keys);
System.out.println(value);
}catch (Exception e) {
logger.error("Failed to parse JSON File: {}", jsonFile.getName());
}
}
You can use Jackson Databind as well.
Create a POJO class. For example :
public class POJO {
private int id;
private String name;
private String couverage;
private String completness;
private String consistency;
// getters, setters and constructors
}
Modify the JSON in the file.
[
{
"id":0,
"name": "project1",
"couverage": "100",
"completness": "44.8",
"consistency": "46"
},
{
"id":1,
"name": "project2",
"couverage": "100",
"completness": "44.8",
"consistency": "46"
},
{
"id":2,
"name": "project3",
"couverage": "100",
"completness": "44.8",
"consistency": "46"
}
]
Code :
public void readfromJsonFile(File jsonFile, long readTimeStamp) {
logger.info("Read from JSON file: {}", jsonFile.getName());
try {
ObjectMapper objectMapper = new ObjectMapper();
POJO[] pojos = objectMapper.readValue(jsonFile, POJO[].class);
for (int i = 0; i < pojos.length; ++i) {
System.out.println(pojos[i].getId());
}
} catch (Exception e) {
logger.error("Failed to parse JSON File: {}", jsonFile.getName());
}
}
Try it like this
JSONArray array_= new JSONArray(content);
JSONObject obj = (JSONObject) array_.get(0);// or any index
then you can use the Object.
I have a json object as below.
{
"products": [
{
"details": {
"name": "xxx",
"price": "100rs"
},
"description": "Buy this product"
}, {
"details": [{
"name": "yyy",
"price": "200rs"
}],
"description": "another project"
}
]
}
Here the details are presented in 2 formats. How can I create a POJO (Plain Old Java Object) class of this to use for the Retrofit api?
I think that's bad api response and should be fixed from backend. But if you want to address the problem, you have to deserialize response to String using String converter. You can't do deserialize it to your Pojo using Gson converter.
StringConverter.java
public class StringConverter implements Converter {
#Override
public Object fromBody(TypedInput typedInput, Type type) throws ConversionException {
String text = null;
try {
text = fromStream(typedInput.in());
} catch (IOException ignored) { }
return text;
}
#Override
public TypedOutput toBody(Object o) {
return null;
}
public static String fromStream(InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
String newLine = System.getProperty("line.separator");
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
out.append(newLine);
}
return out.toString();
}
}
API Call implementation
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(API_URL)
.setConverter(new StringConverter())
.build();
YourAPI api = restAdapter.create(YourAPI.class);
api.yourService(parameter,new RestCallback<String>() {
#Override
public void success(String response, Response retrofitResponse) {
super.success(response, retrofitResponse);
//process your response here
//convert it from string to your POJO, JSON Object, or JSONArray manually
}
#Override
public void failure(RetrofitError error) {
super.failure(error);
}
});
I am newbie in JAVA and trying to convert JSON data format to XML for multiple records. The result is not a well defined XML structure.The below code is working fine when a single record of item exists.
{
"items": [
{
"item": {
"ID": "79C675F752491945E1A",
"Subject": "test1 ",
"Sender": "user1",
"Date": "2014-07-14 14:14:40",
"DocumentClassID": "1",
"Comment": "",
}
},
{
"item": {
"ID": "79C67761945E1A",
"Subject": "test2",
"Sender": "user2",
"Date": "2014-07-14 14:14:40",
"DocumentClassID": "1",
"Comment": "",
}
}
]
}
===================Code Snippet=============================
public class ConvJsonXml extends AbstractTransformation {
public void transform(TransformationInput in, TransformationOutput out) throws StreamTransformationException {
try {
String sourcexml = ""; String targetxml =""; String line ="";
InputStream ins = in.getInputPayload().getInputStream();
BufferedReader br = new BufferedReader( new InputStreamReader(ins));
while ((line = br.readLine()) != null)
sourcexml +=line+"\n";
br.close();
JSONObject o = new JSONObject(sourcexml);
targetxml = org.json.XML.toString(o);
out.getOutputPayload().getOutputStream().write(targetxml.getBytes());
}
catch (Exception e) {
throw new StreamTransformationException(e.getMessage());
}
}
}
Please suggest me to add code in the Try block so that the conversion provides a well uniform XML structure.
Regards..