How to create a json file using existing json file as template? - java

I have a json file which is mostly standard for all my work, the only difference is few parameters.
Now I want to know how can I using java use this json file as a template and provide the parameters as input and save the new json file on local directory?
{
"key" : "HWM_NAME",
"value" : "PINE_SLS_SVC_CUST_CNTCT"
}, {
"key" : "TOPIC",
"value" : "SLS_SVC_CUST_CNTCT2"
}, {
"key" : "SRC_SCHEMA",
"value" : "party_pkg"
}, {
"key" : "SRC_TABLE",
"value" : "SLS_SVC_CUST_CNTCT"
}, {
"key" : "TGT_SCHEMA",
"value" : "mstrdata_hub"
}, {
"key" : "TGT_TABLE",
"value" : "SLS_SVC_CUST_CNTCT"
} ]
},
So here I wish to just change the Value: "PINE_SLS_SVC_CUST_CNTCT" to some other value that I would take as input from user and give me a new json file with those values.
PS: I am working on Java Swing to create a GUI to get the parameters from the user and provide the json file as output.enter image description here
this is how GUI looks

Consider using some JSON Library, for example GSon
Read the values from json
List<LinkedTreeMap> values = gson.fromJson(json, ArrayList.class);
...
update the values, here you can write values from UI components!!!!
for (LinkedTreeMap pair : values) {
//Update values
System.out.println(pair.toString());
}
And generate JSON from java objects
import com.google.gson.Gson;
import com.google.gson.internal.LinkedTreeMap;
...
Gson gson = new Gson();
String json = gson.toJson(values);

Related

JSON serialisation of an array when I add data

I have a form that allows me to input data about a single Item. Every time someone submits an Item, I want to add it to a JSON array, which is stored in a file.
Here's my code:
for (Item obj : list) {
out.print(obj.getId());
out.println("");
out.print(obj.getProductName());
out.println("");
out.print(obj.getPrice());
out.println("");
out.print(obj.getType());
out.println("");
}
ObjectMapper mapper = new ObjectMapper();
File file=new File("D:\\extern_2\\src\\java\\JSON\\jsonlist.json");
if (!file.exists()) {
file.createNewFile();
}
PrintWriter print = new PrintWriter(new BufferedWriter(new FileWriter(file, true)));
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writerWithDefaultPrettyPrinter().writeValue(print, list);
The problem is that every time I add a new Item, a new JSON array is created and appended to the existing file contents.
Desired output:
[ {
"id" : 56,
"productname" : "kklll",
"price" : "56",
"type" : "Hot Coffee",
"productName" : "kklll"
} , {
"id" : 89,
"productname" : "llll",
"price" : "43",
"type" : "Drinks",
"productName" : "llll"
} ]
Actual output:
[ {
"id" : 56,
"productname" : "kklll",
"price" : "56",
"type" : "Hot Coffee",
"productName" : "kklll"
} ][ {
"id" : 89,
"productname" : "llll",
"price" : "43",
"type" : "Drinks",
"productName" : "llll"
} ]
Why is it appending a new array instead of adding my new Item to the existing array?
Look at the FileWriter you are creating: new FileWriter(file, true). That second parameter tells the FileWriter to simply append information to the end of the file. If you are modifying existing JSON, you will need to overwrite the file every time. This means that the first time you create an Item, the ObjectMapper will write it out as a valid JSON string, representing an array with a single object. The second time you create an Item, it will do the same thing for your new object, creating an array with only one object (the second Item) and writing it to the file, even though that file already contains an array. At no point are you actually looking at the file to see if it contains any existing data. You are also not parsing your file into JSON, which would allow you to take an existing JSON array and add something to it.
Your process should be like this:
Read in your existing data in your file, using the ObjectMapper. Since your file contains an array of Item objects, you should end up with a List<Item> after you've read in your file
Add your new Item to the List
Convert your List<Item> to JSON and write it to your .json file. Make sure to overwrite your .json file, not just append to it.

Cloudera Navigator API fail to fetch nested data

I am working in Cloudera Manager Navigator REST API where extracting result is working fine, but unable to get any nested value.
The type of data is extracting as below.
{
"parentPath": "String",
"customProperties": "Map[string,string]",
"sourceType": "String",
"entityType": "String"
}
And data should be like
{
"parentPath": "abcd",
"customProperties": {
"nameservice" : "xyz"
},
"sourceType": "rcs",
"entityType": "ufo"
}
But I am getting key-value result as follows.
parentPath :abcd
customProperties : null
sourceType : rcs
entityType : ufo
In above response data, "customProperties" is coming with a null value where it should return a map object contains ["nameservice" : "xyz"]. This is the problem with following code snippet.
MetadataResultSet metadataResultSet = extractor.extractMetadata(null, null,"sourceType:HDFS", "identity:*");
Iterator<Map<String, Object>> entitiesIt = metadataResultSet.getEntities().iterator();
while(entitiesIt.hasNext()){
Map<String, Object> result = entitiesIt.next();
for(String data : result.keySet()){
System.out.println(" key:"+data+" value:"+result.get(data));
}
}
Can you suggest me how to get the nested value where datatype is complex.
have u checked how the data looks on navigator ui? You can first verify that once, and also try cloudera /entities/entity-id rest API in browser to check how json response is coming

How to store GeoLocation in model class in Java?

So this is JSON object:
[
{
"address" : {
"street" : "VanderWyk",
"housenumber" : "456",
"postalcode" : "3061 WL GA",
"city" : "Roterdam",
"geoLocation" : {
"lat" : "50.555011",
"lng" : "5.894267"
}
},
"type" : "PWS"
}, {
address...
}
]
I know how to handle single objects but I don't know how to handle geoLocation which is Json object in itself. To define it as an String array? How should I store this in a model class? Database? And then when I'm consuming this data from front-end..what will be easiest way to do that? How to write REST service to do such a thing?
Any help would be appreciated?
I recommend using a JSON-seralizer such as Jackson.
Then, for example, you can have a GeoLocation class. Then your main object class can have a property that is an instance of GeoLocation. When de-seralizing the JSON, it will interpret the geoLocation field in the JSON and create a GeoLocation object for it.

Forming Json from txt file

I have this data in my text file.
Obj1= {
"AA" : "sasa",
"BB" : "fdsfsf",
"CC" : "sfsdf",
"DD" : "kmdksmd",
"EE" : "dsnjsdn"
};
Obj2= {
"DD" : "ndjsdnsjd",
"MM" : "jskdjskadn"
};
This data is in a single text file. How do I convert this to two different objects in JAVA
Is it possible to use more friendly, fully JSON format instead? It might look like:
{
"Obj1" : {
"AA" : "sasa",
"BB" : "fdsfsf",
"CC" : "sfsdf",
"DD" : "kmdksmd",
"EE" : "dsnjsdn"
},
"Obj2" : {
"DD" : "ndjsdnsjd",
"MM" : "jskdjskadn"
}
}
Then it would be very easy to load it like described in this thread
The file from your example isn't the correct JSON file so you can't do that so easily. If you really want to stick with your format, you would have to somehow tokenize/parse the file first to extract valid JSON fragments and than pass it to e.g. GSON library to convert them to objects.
If these will be small files like from your example, you can just load the whole file to string and try use regular expressions (with groups) and/or StringTokenizer to extract JSON chunks.

Converting Nested Json files to CSV in java

{
"Employee": [
{
"empMID": "mock:1",
"comments": [],
"col1": "something",
"contact": [{"address":"2400 waterview", "freetext":true}
],
"gender": "male"
},
{
"empMID": "mock:2",
"comments": [],
"col1": "something",
"contact": [{"address":"2200 waterview", "freetext":true}
],
"gender": "female"
}
],
"cola": false,
"colb": false
}
This is how my Json file looks .I m required to convert this json to a csv .(I m trying to convert a multi-dimesional data to 2d).I m using gson for my purpose.I cannot use gson.fromgson() function to object map with a template because it should be generic .
I know we can use CDL to convert jsonarray to csv format but It wont work in my case .
my csv format looks like
Employee*
empMID,comment.$,contact.address,contact.freetext,gender
mock:1,,2400 waterview,TRUE,male
mock:123,,2200 waterview,TRUE,female
colA#
TRUE
colB#
FALSE
I tried using google-GSON api to convert to this format .But I m not able to convert to this format .I have used * to represent its a json array and # to represent its a primitive type and contact.address to represent nested array inside another json array .I having problem relating this nested structure .I m able to traverse everything recursively like a column. Thanks in advance
public static void main(String[] args) throws IOException{
BufferedReader reader=null;
StringBuilder content=null;
String result=null;
reader = new BufferedReader(new FileReader("temp.json"));
String line = null;
content= new StringBuilder();
while ((line = reader.readLine()) != null) {
content.append(line);
}
reader.close();
result= content.toString();
JsonElement jelement = new JsonParser().parse(result);
printJsonRecursive(jelement);
}
public static void printJsonRecursive(JsonElement jelement){
if(jelement.isJsonPrimitive()){
System.out.println(jelement.getAsString());
return;
}
if(jelement.isJsonArray()){
JsonArray jarray= jelement.getAsJsonArray();
for(int i=0;i<jarray.size();i++){
JsonElement element= jarray.get(i);
printJsonRecursive(element);
}
return;
}
JsonObject jobject= jelement.getAsJsonObject();
Set<Entry<String, JsonElement>> set= jobject.entrySet();
for (Entry<String, JsonElement> s : set) {
printJsonRecursive(s.getValue());
}
}
}
You can achieve this thru reflection if you have a object mapped to the json.
use gson/jackson to convert json to java object
append fields using reflection by iterating the class and get any field you interested in.
append value with reflection by getting value from the target object.
More detail look at my blog post below:
vcfvct.wordpress.com/2015/06/30/converting-nested-json-files-to-csv-in-java-with-reflection/
You are not printing the key. This should fix it.
for (Entry<String, JsonElement> s : set) {
System.out.println(s.getKey()); //Added
printJsonRecursive(s.getValue());
}
You can take care of \ns from here.
EDIT
If you want to print the keys just once for repeating json objects, create a Java bean to hold the data and populate it during your recursion. Once the bean is complete, add a method there to print all the data in the format you want (printing keys only once and so on).
You can use the library json2flat for converting your JSON to CSV.
This library doesn't require any POJO's. It simply takes your JSON as string and returns a 2D representation of it in the format of List<Object[]>.
For example for the JSON:
{
"Employee": [
{
"empMID": "mock:1",
"comments": [],
"col1": "something",
"contact": [{"address":"2400 waterview", "freetext":true}
],
"gender": "male"
},
{
"empMID": "mock:2",
"comments": [],
"col1": "something",
"contact": [{"address":"2200 waterview", "freetext":true}
],
"gender": "female"
}
],
"cola": false,
"colb": false
}
It gives an output:
/cola,/colb,/Employee/empMID,/Employee/col1,/Employee/gender,/Employee/contact/address,/Employee/contact/freetext
,,"mock:1","something",,"2400 waterview",true
,,"mock:2","something",,"2200 waterview",true
false,false,,,,,
/**
* Get separated comlumns used a separator (comma, semi column, tab).
*
* #param headers The CSV headers
* #param map Map of key-value pairs contains the header and the value
*
* #return a string composed of columns separated by a specific separator.
*/
private static String getSeperatedColumns(Set<String> headers, Map<String, String> map, String separator) {
List<String> items = new ArrayList<String>();
for (String header : headers) {
String value = map.get(header) == null ? "" : map.get(header).replaceAll("[\\,\\;\\r\\n\\t\\s]+", " ");
items.add(value);
}
return StringUtils.join(items.toArray(), separator);
}

Categories