Inserting JSON Subobject into existing JSON - java

I get JSON back from a web service call that looks like this:
{
results :
{
seg: {
segName: whatever,
segType: atest,
var: [
{field1: value1,
field2: value2,
field3: value3},
{field1: value4,
field2: value5,
field3: value6}
]
}
}
}
I am using the net.sf.json package in Java. I create a JSON object from this result.
I would like to manually add another entry (JSONObject) to the array "var".
Other than deconstructing the object all the way down to the JSONArray "var", and then rebuilding it, is there a way to just insert another entry into var?
I tried accumulate("var", new JSONObject(...)); but that stuck the new object at the same level as "seg" in the "results" section.

You have to call accumulate at the level you want the new object inserted.
If you drill down to the "seg" level, and accumulate the new object there, you'll add the new entry to the "var" array.
e.g.
String json = // your input JSON string here
JSONObject obj = new JSONObject(json);
obj.getJSONObject("results")
.getJSONObject("seg")
.accumulate("var", new JSONObject("{field1 : value7, field2: value8, field3: value9}"));
System.out.println(obj);
gives
{"results":{"seg":{"var":[{"field3":"value3","field2":"value2","field1":"value1"},{"field3":"value6","field2":"value5","field1":"value4"},{"field3":"value9","field2":"value8","field1":"value7"}],"segType":"atest","segName":"whatever"}}}

Related

Simplest way to convert this array in to the specified one using Java

I have this String Json Payload
[
"key1":{
"atr1":"key1",
"atr2":"value1",
"atr3":"value2",
"atr4":"value3,
"atr5":"value4"
},
"key2":{
"atr1":"key2",
"atr2":"value5",
"atr3":"value6",
"atr4":value7,
"atr5":"value8"
}
]
and I want it to be converted in to the following format using Java
[
{
"atr2":"value1",
"atr3":"value2",
"atr4":"value3,
"atr5":"value4"
},
{
"atr2":"value5",
"atr3":"value6",
"atr4": "value7",
"atr5":"value8"
}
]
What would be the simplest way of transforming this ?
You cannot, because the example below is not valid json.
Check it out using this JSON validator.
If you paste this in (I've fixed some basic errors with lack of quotes)
{
{
"atr2":"value1",
"atr3":"value2",
"atr4":"value3",
"atr5":"value4"
},
{
"atr2":"value5",
"atr3":"value6",
"atr4":"value7",
"atr5":"value8"
}
}
You will get these errors ...
It can work if you change the target schema to something like this by using a json-array to contain your data.
[
{
"atr2":"value1",
"atr3":"value2",
"atr4":"value3",
"atr5":"value4"
},
{
"atr2":"value5",
"atr3":"value6",
"atr4":"value7",
"atr5":"value8"
}
]
If this works for you, then this problem can easily be solved by using the ObjectMapper class.
You use it to deserealize the original JSON into a class, which has two fields "key1" and "key2"
Extract the values of these fields and then just store them in an array ...
Serialize the array using the ObjectMapper.
Here a link, which explains how to use the ObjectMapper class to achieve the goals above.
EDIT:
So you'll need the following classes to solve the problem ...
Stores the object data
class MyClass {
String atr2;
String art3;
}
Then you have a container class, which is used to store the initial json.
class MyClassContainer {
MyClass key1;
MyClass key2;
}
Here's how you do the parse from the original json to MyClassContainer
var mapper = new ObjectMapper()
var json = //Get the json String somehow
var myClassContainer = mapper.readValue(json,MyClassContainer.class)
var mc1 = myClassContainer.getKey1();
var mc2 = myClassContainer.getKey2();
var myArray = {key1, key2}
var resultJson = mapper.writeValueAsString(myArray)
Assuming that you will correct the JSON into a valid one (which involves replacing the surrounding square braces with curly ones, and correct enclosure of attribute values within quotes), here's a simpler way which involves only a few lines of core logic.
try{
ObjectMapper mapper = new ObjectMapper();
mapper.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false );
HashMap<String, Data> map = mapper.readValue( jsonString, new TypeReference<HashMap<String, Data>>(){} );
String json = mapper.writeValueAsString( map.values() );
System.out.println( json );
}
catch( JsonProcessingException e ){
e.printStackTrace();
}
jsonString above is your original JSON corrected and valid JSON input.
Also notice the setting of FAIL_ON_UNKNOWN_PROPERTIES to false to allow atr1 to be ignored while deserializing into Data.
Since we are completely throwing away attr1 and its value, the Data class will represent all fields apart from that.
private static class Data{
private String atr2;
private String atr3;
private String atr4;
private String atr5;
}

How to construct this JSON array of JSONObjects

I have a Problem which I have to solve in Java.I have a data in YAML where the data is in this structure
600450:
STATE:STATE1
CITY:CITY1
ID:1
CONTACT:1234
600453:
STATE:STATE1
CITY:CITY1
ID:2
CONTACT:3456
600451:
STATE:STATE2
CITY:CITY2
ID:3
CONTACT:2234
.....
I converted this into JSONObject but I am strugling to change this into this JSONObject object where the structure should be of this form
{
STATE1:
{[
CITY1:{
[{ID:1,CODE:600450,CONTACT:1234},
{ID:2,CODE:600453,CONTACT:3456}
]
},
CITY2:{
[
{ID:3,CODE:600451,CONTACT:1234}
]
}
]}
}
I have almost lost a hour by doing different Things with JSONObject and JSONArray and then switched to HashMap and ArrayList of HashMap but I am not able to get it !
This was my try I am sure this is absurd I know that How to achieve this in Java .
Assuming that your converted initial JSON looks like this:
{
"600450": {
"STATE": "STATE1",
"CITY": "CITY1",
"ID": 1,
"CONTACT": 1234
},
"600451": {
"STATE": "STATE2",
"CITY": "CITY2",
"ID": 3,
"CONTACT": 2234
},
"600453": {
"STATE": "STATE1",
"CITY": "CITY1",
"ID": 2,
"CONTACT": 3456
}
}
Here is a static method that does the full conversion to your desired format:
static JSONObject convert(JSONObject initial) {
// STATE -> CITY -> Address[]
Map<String, Map<String, List<Map<String, Object>>>> stateToCityToAddresses = new HashMap<>();
// Get list of codes
String[] codes = JSONObject.getNames(initial);
// Loop over codes - "600450", "600451", "600453", ...
for (String code : codes) {
// Get the JSONObject containing state data
JSONObject state = initial.getJSONObject(code);
// Extract information from state JSONObject
String stateName = state.getString("STATE");
String cityName = state.getString("CITY");
long id = state.getLong("ID");
long contact = state.getLong("CONTACT");
// Some Java 8 awesomeness!
List<Map<String, Object>> addresses = stateToCityToAddresses
.computeIfAbsent(stateName, sn -> new HashMap<>()) // This makes sure that there is a Map available to hold cities for a given state
.computeIfAbsent(cityName, cn -> new ArrayList<>()); // This makes sure that there is a List available to hold addresses for a given city
// Save data in a map representing a json object like: {"CONTACT":1234,"CODE":600450,"ID":1}
Map<String, Object> address = new HashMap<>();
address.put("ID", id);
address.put("CONTACT", contact);
address.put("CODE", Long.parseLong(code));
// Add the address under city
addresses.add(address);
}
// Just use the JSONObject.JSONObject(Map<?, ?>) constructor to get the final result
JSONObject result = new JSONObject(stateToCityToAddresses);
// You can sysout the result to see the data
// System.out.println(result);
return result;
}
Allow me to play Devil's Advocate.
I think you may risk deviating away from the relationships that have been described in the .yaml. You should try to avoid embedding any application-specific logic inside of your data models, since your assumptions may land you in trickier places in the future.
Generally speaking, you should respect the initial form of the data and interpret the relationships or associated logic with the flexibility of runtime processing. Otherwise, you end up serializing data structures which do not correlate directly with the source, and your assumptions may land you in a hot spot.
The "real" JSON equivalent, I suspect; would look something like this:
{
"600450": {
"STATE": "STATE1",
"CITY": "CITY1",
"ID": 1,
"CONTACT": 1234
},
"600453": { ...etc }
}
It would still be possible to pair these relationships. If you want to relate all Objects by city, you could first separate them into bins. You could do this by using a Map which relates a String city to a List of JSONObjects:
// This will be a Map of List of JSONObjects separated by the City they belong to.
final Map<String, List<JSONObject>> mCityBins = new ArrayList();
// Iterate the List of JSONObjects.
for(final JSONObject lJSONObject : lSomeListOfJSONObjects) {
// Fetch the appropriate bin for this kind of JSONObject's city.
List<JSONObject> lBin = mCityBins.get(lJSONObject.get("city"));
// Does the right bin not exist yet?
if (lBin == null) {
// Create it!
lBin = new ArrayList();
// Make sure it is in the Map for next time!
mCityBins.add(lJSONObject.get("city"), lBin);
}
// Add the JSONObject to the selected bin.
lBin.add(lJSONObject);
}
Whilst you process the JSONObjects, whenever you come across a city whose key does not exist in the Map, you can allocate a new List<JSONObject>, add the current item to that List and add it into the Map. For the next JSONObject you process, if it belongs to the same city, you'd find the existing List to add it to.
Once they're separated into bins, generating the corresponding JSON will be easy!
As I see your git repo you just try to convert first Json structure to new Structure you want. I must to tell you probably you could create this structure directly from YAML file.
As I don't see your first Json structure so I guess that must be something like this :
{600450:{STATE:STATE1 , CITY:CITY2 , ...} , ...}
If this is true so this way can help you :
public static JSONObject convert(JSONObject first) throws JSONException {
HashMap<String , HashMap<String , JSONArray>> hashMap = new HashMap<>();
Iterator<String> keys = first.keys();
while (keys.hasNext())
{
String key = keys.next();
JSONObject inner = first.getJSONObject(key);
String state = inner.getString("STATE");
HashMap<String , JSONArray> stateMap =
hashMap.computeIfAbsent(state , s -> new HashMap<>());
String city = inner.getString("CITY");
JSONArray array = stateMap.computeIfAbsent(city , s->new JSONArray());
JSONObject o = new JSONObject();
o.put("ID" , inner.getInt("ID"));
//in this section you could create int key by calling Integer.parse(String s);
o.put("CODE" , Integer.valueOf(key));
o.put("CONTACT" , inner.getInt("CONTACT"));
array.put(o);
}
JSONObject newStructureObject = new JSONObject();
for(String stateKey:hashMap.keySet())
{
JSONArray array = new JSONArray();
JSONObject cityObject = new JSONObject();
HashMap<String , JSONArray> cityMap = hashMap.get(stateKey);
for(String cityKey : cityMap.keySet())
{
cityObject.put(cityKey , cityMap.get(cityKey));
}
array.put(cityObject);
newStructureObject.put(stateKey , array);
}
return newStructureObject;
}

append json object to existing array of json object

I am trying to append new json object in existing json array of object. I am new in json. so please help me.
existing json :
{
"cluster":[
{
"path":"home/Nik",
"password":"welcome",
"isQueen":"true",
"host":"192.168.11.248",
"isQueenWorker":"true",
"user":"Nik"
}
]
}
new json :
{
"path":"home\/Nik",
"password":"welcome",
"isQueen":"true",
"host":"192.168.11.248",
"isQueenWorker":"true",
"user":"Nik"
}
I want to add new json to existing json array.
You may use it like below, you need to use push command to push an object inside an array.
var myObj = {
"cluster":[
{
"path":"home/Nik",
"password":"welcome",
"isQueen":"true",
"host":"192.168.11.248",
"isQueenWorker":"true",
"user":"Nik"
}
]
};
var x = {
"path":"home\/Nik",
"password":"welcome",
"isQueen":"true",
"host":"192.168.11.248",
"isQueenWorker":"true",
"user":"Nik"
};
alert(JSON.stringify(myObj))
var newArr = myObj.cluster;
newArr.push(x) //pushing object x in newArr. similarly you can add multiple objects in to it
var myJSON = JSON.stringify(newArr);
alert(myJSON)
you can directly append it
eg. first json
{"cluster":[{"path":"home/Nik","password":"welcome","isQueen":"true","host":"192.168.11.248","isQueenWorker":"true","user":"Nik"}]}
int i= cluster.length();
cluster[i]={"path":"home/Nik","password":"welcome","isQueen":"true","host":"192.168.11.248","isQueenWorker":"true","user":"Nik"}

Get JSON key name using GSON

I have a JSON array which contains objects such as this:
{
"bjones": {
"fname": "Betty",
"lname": "Jones",
"password": "ababab",
"level": "manager"
}
}
my User class has a username which would require the JSON object's key to be used. How would I get the key of my JSON object?
What I have now is getting everything and creating a new User object, but leaving the username null. Which is understandable because my JSON object does not contain a key/value pair for "username":"value".
Gson gson = new Gson();
JsonParser p = new JsonParser();
JsonReader file = new JsonReader(new FileReader(this.filename));
JsonObject result = p.parse(file).getAsJsonObject().getAsJsonObject("bjones");
User newUser = gson.fromJson(result, User.class);
// newUser.username = null
// newUser.fname = "Betty"
// newUser.lname = "Jones"
// newUser.password = "ababab"
// newUser.level = "manager"
edit:
I'm trying to insert "bjones" into newUser.username with Gson, sorry for the lack of clarification
Use entrySet to get the keys. Loop through the entries and create a User for every key.
JsonObject result = p.parse(file).getAsJsonObject();
Set<Map.Entry<String, JsonElement>> entrySet = result.entrySet();
for(Map.Entry<String, JsonElement> entry : entrySet) {
User newUser = gson.fromJson(p.getAsJsonObject(entry.getKey()), User.class);
newUser.username = entry.getKey();
//code...
}
Using keySet() directly excludes the necessity in iteration:
ArrayList<String> objectKeys =
new ArrayList<String>(
myJsonObject.keySet());
Your JSON is fairly simple, so even the manual sort of methods (like creating maps of strings etc for type) will work fine.
For complex JSONs(where there are many nested complex objects and lists of other complex objects inside your JSON), you can create POJO for your JSON with some tool like http://www.jsonschema2pojo.org/
And then just :
final Gson gson = new Gson();
final MyJsonModel obj = gson.fromJson(response, MyJsonModel.class);
// Just access your stuff in object. Example
System.out.println(obj.getResponse().getResults().get(0).getId());

How to properly format JSON string in java?

I have a jersey client that is getting JSON from a source that I need to get into properly formatted JSON:
My JSON String looks like the folllowing when grabbing it via http request:
{
"properties": [
{
someproperty: "aproperty",
set of data: {
keyA: "SomeValueA",
keyB: "SomeValueB",
keyC: "SomeValueC"
}
}
]
}
I am having problems because the json has to be properly formatted and keyA, keB, and keyC are not surrounded in quotes. Is there some library that helps add quotes or some best way to go about turning this string to properly formatted json? Or if there is some easy way to convert this to a json object without writing a bunch of classes with variables and lists that match the incoming structure?
you can use json-lib. it's very convenient! you can construct your json string like this:
JSONObject dataSet = new JSONObject();
dataSet.put("keyA", "SomeValueA") ;
dataSet.put("keyB", "SomeValueB") ;
dataSet.put("keyC", "SomeValueC") ;
JSONObject someProperty = new JSONObject();
dataSet.put("someproperty", "aproperty") ;
JSONArray properties = new JSONArray();
properties.add(dataSet);
properties.add(someProperty);
and of course you can get your JSON String simply by calling properties.toString()
I like Flexjson, and using lots of initilizers:
public static void main(String[] args) {
Map<String, Object> object = new HashMap<String, Object>() {
{
put("properties", new Object[] { new HashMap<String, Object>() {
{
put("someproperty", "aproperty");
put("set of dada", new HashMap<String, Object>() {
{
put("keyA", "SomeValueA");
put("keyB", "SomeValueB");
put("keyC", "SomeValueC");
}
});
}
} });
}
};
JSONSerializer json = new JSONSerializer();
json.prettyPrint(true);
System.out.println(json.deepSerialize(object));
}
results in:
{
"properties": [
{
"someproperty": "aproperty",
"set of dada": {
"keyA": "SomeValueA",
"keyB": "SomeValueB",
"keyC": "SomeValueC"
}
}
]
}
Your string isn't JSON. It's something that bears a resemblance to JSON. There is no form of JSON that makes those quotes optional. AFAIK, there is no library that will reads your string and cope with the missing quotes and then spit it back out correctly. You need to find the code that produced this and repair it to produce actual JSON.
You can use argo, a simple JSON parser and generator in Java

Categories