How to convert a JSONobject into an object map? - java

I’ve been trying to create a dynamic text-grabbing system to be able to translate future programs into different languages more easily. I’m fairly new to Java, so I’m not well versed on the data types that there are, but would it be possible to take a JSON object (using simple.json) and converting it into something that I could reference easily and concisely?
For example given a JSON string:
{
"name": "John Doe",
"country": "US",
"age": 25,
"family": {
"immediate": {
"spouse": "Johnette Doe",
"children": [
{
"name": "Jimbles Doe",
"age": "213"
}
]
}
}
}
How could I set my file up so that I could reference it like so:
JohnClass.family.immediate.children[0].name
and get a value in return?

Get Jackson (either use the maven dependency or download the jar): http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind/2.5.0
Untested code below, and to be honest a effortless punt, just to help you sort it quickly.
Instantiate JSONMapper (ideally in a constructor):
ObjectMapper mapper = new ObjectMapper();
Convert to Hashmap (you could also convert to any other object):
Map map = mapper.readValue("JSON_STRING_HERE", new TypeReference<HashMap>(){});
Access like this:
map.get("family").get("immediate").get("children").get(0).get("name");
You could also just use JSONObject which also implements the Map interface, but if you get used to do it this way you'll know how to do it for other objects.

Related

Extract subset of json from given JsonPath

I have a nested json structure and a list of json paths. I want to extract and return only those parts of json that are defined in the json paths.
For eg: Let's say the json contains:
{
"id": 1,
"user": {
"name": "ABCD",
"email": "abcd#email.com",
"phone": "1234"
}
}
And I've the following JsonPath's
$.id
$.user.name
$.user.phone
So the json returned will be
{
"id": 1,
"user": {
"name": "ABCD",
"phone": "1234"
}
}
I've tried multiple ways with Jayway's JsonPath but I only get the value, not the entire heirarchy(Eg: If I search for $.user.name then I get ABCD instead of {"user": {"name": "ABCD"}}).
I looked at Extracting a subset of attributes with JSONPath but it does not answer the question of return entire json structure.
Any ideas how do I approach this? I suspect that I would need to build Jackson JsonNode iteratively using the JsonPath, but couldn't build a solution.
Note: The example above contains a simple json structure. In reality, I suspect to have many nested structures(even arrays) inside json.

Extract and Crete new JSON string

I have some spring MVC based APIs which produces JSON/ XML which represents API output.
{
"data" :
{
"users": [
{
"id": "001",
"name: "abc1",
"type": {
"id": "P",
"name": "Permanent"
}
},
{
"id": "002",
"name: "xyz",
"type": {
"id": "C",
"name": "Contractor"
}
}
]
}
}
I'm passing a parameter with request as
url?fields=users.id, users.type.id
users.type.id is a sub-node in users node.
users node is an array.
Now, what I want to do is to filter those only properties and create the response based upon fields passed in the request.
So the response to above filter condition should be same structure and will only contain wanted fields with values.
I'm trying to build a flat map with keys with a dot notation so I won't lose the track to filter, then I'll rebuild the JSON again. I feel this approach is just unreasonable because Jackson has the .path and .with API's to check existing path. But the real challenge is to extract and create a new JSON which matches the response JSON.
I'm looking for some ideas to achieve this. I don't want to try any third party libs btw. I know some libs are there. I want to prefer Jackson way to do this.
Feel free to add or comment if you have a further ideas.

Parsing a subset of JSON in Java using Jackson

Given a Json, is it possible to use Jackson to only parse out a section of the message?
Say that the data I'm interested in is buried in a deep hierarchy of fields and I simply do not care about creating DTO classes for each and every class.
Given a very simplified scenario I'd like to model the Telephone class without knowing anything about the structure before it:
...{
"firstName": "John",
"lastName" : "doe",
"age" : 26,
"address" : {
"streetAddress": "naist street",
"city" : "Nara",
"postalCode" : "630-0192"
},
"phoneNumbers": [
{
"type" : "iPhone",
"number": "0123-4567-8888"
},
{
"type" : "home",
"number": "0123-4567-8910"
}
]
}....
I'm thinking something in the terms of using json-path together with deserializing just the parts I'm interested of. Some pseudo:
List<Telephone> phoneNrs = parse(".my.deep.structure.persons.phoneNumbers", List<Telephone.class>);
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readTree("... your JSON ...");
Using the JsonNode object you can then call get("my").get("deep").get("structure") to get the node you want.
Once you got your hands on that node, a simple call to mapper.treeToValue(myDeepJsonNode, Telephone[].class) will get you your array ofTelephone. You can get a list using a TypeReference as well.
To get to your deep JsonNode you can also use the findValue and findPath methods.
The Javadoc:
https://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/JsonNode.html
Yes, it is possible the way you have mentioned in the Pseudo code. "phoneNumbers" is a key and value returned can be passed on to Jackson deserialiying.
If the response is an array of maps then you can iterate through each one of them and use the yourResponseAsJSONObject.get('phoneNumbers') method to get the value and pass it on to Jackson
or use JsonPath as mentioned by #dimas
You can use JsonPath library. With this library you can map your JsonPath output directly into POJO's.
Pseudo:
List<Telephone> phoneNrs = JsonPath.parse(json).read("$.my.deep.structure.persons.phoneNumbers", List.class);
To do this efficiently with Jackson, use the Streaming API via the JsonParser class (http://fasterxml.github.io/jackson-core/javadoc/2.5/com/fasterxml/jackson/core/JsonParser.html).
This approach will allocate no additional memory and will not incur the cost of deserializing values for all of the skipped data. Since the code will be much longer and more difficult to read than using Jackson's ObjectMapper, only do this if profiling shows unacceptable GC activity or CPU usage during parsing.
You can skip all of the nodes that you are uninterested in until you hit the "phoneNumbers" key. Then you can call the readValueAs function to deserialize the array of phone number dictionaries like so readValueAs(new TypeReference<MyPhoneNumberType[]>()).
See also:
a tutorial on reading and writing with JsonParser: http://www.cowtowncoder.com/blog/archives/2009/01/entry_132.html
The main documentation: https://github.com/FasterXML/jackson-core

Using JsonPath to extract value without knowing key

I have a json string like this:
"files": {
"fileA.c": {
"size": 100
},
"fileB.txt": {
"size": 200
}
}
I want to extract the file names, {"fileA.c","fileB.txt"}, using JsonPath. Note that the number of files is unknown.
The problem is, I don't know whether the file name is a key or a value:
If it is a key...well I certainly don't know the key name because that's the information I want to extract.
If it is a value, then what is its key?
Can I use JsonPath to extract the file names? If so, how?
If JsonPath cannot do this, is there any Java library for Json that can achieve this?
In your example, fileA.c and fileB.txt are keys, you can get them by iterating on the key in the enclosing object (which is referenced by the key "files").
I don't think JSONPath is really appropriate (or even applicable) in this case, it is designed to access elements when you know the structure of the documents, which means that basically you know the keys. It would be much easier to simply use a JSON parser.
I would suggest you to modify your data structure, to something like this;
var data = {
"files": [
{
"name": "fileA.c",
"size": 100
},
{
"name": "fileB.txt",
"size": 200
},
{
"name": "fileC.txt",
"size": 50
}
]
};
When structured like this, you can use DefiantJS (http://defiantjs.com) to query for files which sizes are larger than 100...like this:
JSON.search(data, '//*[size >= 100]/name')
DefiantJS extends the global object JSON with the method "search", with which you can query JSON structure with XPath expressions.
To see a working example with your data, check out this fiddle:
http://jsfiddle.net/jRN22/

Need help working with a json formatted string. (Java)

I have the contents of this page stored in a string variable. I've spent hours looking at different ways of working with json in java, and have learned a lot about the build path, dependencies, ssl certificates, and so on. I say that to emphasize the fact that I have been looking for an answer to this question independently. I've finally caved and I need help.
I'm looking for a way to turn this string into some kind of json array so that I could access the individual elements more easily. For example, something along the lines of:
int map = jsonArray[index].getInt("map_Id");
I hope that what I'm trying to do is clear enough. Any help would be appreciated.
edit: I'm currently attempting this with gson but am open to suggestions.
You can use the Jackson libraries used for JSON parsing as follows:
public static int getIntFromJson(String jsonString)
{
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonString);
int id = node.get(0).get("age").asInt();
return id;
}
Assuming that your jsonString will be something like this, the above code will return39.
[
{ "name": "Dagny Taggart", "age": 39 },
{ "name": "Francisco D'Anconia", "age": 40 },
{ "name": "Hank Rearden", "age": 46 }
]
You can pick a library (in this case, to decode JSON) from the Java section at the bottom of: http://json.org
YOu can have a look to the library below:
json-java
You can use the JSONObject to parse a String representing a JSON object and then extract the values you are interested in.

Categories

Resources