Efficiently find a key-value in JSON with JAVA - java

I want to find whether a key-value pair exists in a JSON given a key. This key-value pair may not be under root. It's possible embedded deeply in the document. For example:
{"Persons":[
{"Person":
{"name":"john"}
}]
}
and I want to have something like JsonDoc.has("name"), and return true.
I search online and find this thread: Java: Json has key/field
Two answers (minimal-json and org.json) both has some functioned called has() or get(), but I looked into their source code, they are both trying to find the key-value under root. So they don't meet my needs.
I can think of traversing the whole json and try to find the key-value, but it seems not efficient.

If you use Jackson, you can call findParent on a JsonNode which will look for a field within the node or its descendant.
http://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/JsonNode.html#findParent(java.lang.String)

Related

Parsing a cypher query result (JSON) to a Java object

I use the jersey/jackson stack to address a neo4j database via the REST api, but I have some issues how to interpret the result.
If I read the node by its ID (/db/data/node/xxx) the result can be mapped to my DTO very easy by calling readEntity(MyDto.class) on the response. However, usage of internal IDs is not recommended and various use cases require to query by custom properties. Here cypher comes into play (/db/data/cypher).
Assuming a node exists with a property "myid" and a value of "1234", I can fetch it with the cypher query "MATCH (n {myid: 1234}) RETURN n". The result is a JSON string with a bunch of resources and eventually the "data" I want do unmarshall to a java object. Unmarshalling it directly fails with a ProcessingException (error reading entity from input stream). I see no API allowing to iterate the result's data.
My idea is to define some kind of generic wrapper class with an attribute "data", giving this one to the unmarshaller, and unwrapping my DTO afterwards. I wonder if there is a more elegant way to do this, like using "RETURN n.data" (which does not work) or something like this. Is it?
You should look into neo4j 2.0 where return n just returns the property map.
I usually tend to deserialize the result as a nested list/map (i.e. have ObjectMapper read to Object.class or Map.class) structure and grab the data map directly out of that.
There's probably a way to tell jackson to ignore all the information around that data field
If you want to have a nicer presentation you can also check out my cypher-rs project which returns only the data in question, nothing more.

Steps to convert a Java object to JSON

During a recent job interview, i was asked the steps taken to convert Java object to JSON using Jackson.
Although, I havent done it before, I have seen examples where Jackson was used and by using object mapper the java object is converted to JSON.
However, the interviewer asked "how and where is the JSON schema set up"
I thought this was done automatically. Does one have to specify how the JSON has to be returned?
I have seen examples where the toString is overriden - is that where the schema is specified.
Thanks
I think the interviewer doesn't mean to ask you how to use Jackson, but how JSON is constructed from a Java Object.
Here's what I thought:
Jackson will detect every field's name as keys;
Iterate the keys to get their values and put it into the JSON.
If a field has child object, it will do step 1 and 2 recursively.
Note: The Java class should implementation the serialization interface.

Does the sequence of the values matter in a JSON object?

I have a JSON object which I have constructed within my Java program.
JSONObject jObj = {"AAA:aaa","BBB:bbb","CCC:ccc"}
I am sending this object to a server in which it expects the JSON object in the following type.
{"BBB:bbb", "AAA:aaa", "CCC:ccc"}
My question is that does the order of the JSON object really matters on the server side? If yes, how can I change the order?
My question is that does the order of the JSON object really matters on the server side?
It should not matter. According to various JSON specifications, the order of the attributes is not significant. For example:
"An object is an unordered set of name/value pairs." (Source json.org)
"An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array." (Source RFC 7159)
Unfortunately, there are nitwits out there1 who ignore that aspect of the specs, and place some significance on the order of the attributes. (The mistake is usually made when there is a disconnect between the people specifying the APIs and those implementing them, and the people doing the specification work don't really understand JSON.)
Fortunately, the chances are that whoever designed / implemented the server didn't make that mistake. Most Java JSON parsers I've come across don't preserve the attribute order when parsing ... by default2. It would be hard to accidentally implement a server where the order of the JSON attributes being parsed was significant.
If yes, how can i change the order?
With difficulty, I fear:
You could generate the JSON by hand.
There is at least one JSON for java implementation3 that allows you to supply the Map object that holds a JSON object's attributes. If you use a LinkedHashMap or TreeMap, it should retain the insertion order or the lexical order of the attribute keys.
1 - For example, the nitwits that this poor developer was working for ... https://stackoverflow.com/a/4515863/139985
2 - RFC 7159 also says this: "JSON parsing libraries have been observed to differ as to whether or not they make the ordering of object members visible to calling software. Implementations whose behavior does not depend on member ordering will be interoperable in the sense that they will not be affected by these differences.". By my reading, this recommends that JSON libraries should hide any order of the pairs from application code.
3 - JSON-simple : https://code.google.com/p/json-simple/. There could be others too.
IMHO not possible.
JSON docs says
An object is an unordered set of name/value pairs
So the way is getting the values in required order,rather than ordering json
You could use list assuming your server can accept it:
{"list": [ {"AAA":"aaa"},{"BBB":"bbb"},{"CCC":"ccc"}]}
The other answers rightly point out that the order should not matter. There are circumstances were the order may matter in a specific implementation that misunderstands the unordered nature of JSON.
For example say you want take a hash of the JSON string and store the hash for comparison against future hashes. The hash would be different if the order of the fields in the JSON string is not the same the next time you create the hash (even thought the data in the JSON string is the same).
This can happen if you're working with an API or a deserializer that returns JSON strings, with the fields in an inconsistent order.
This question more thoroughly discusses that issue and provides solutions to getting a consistent order JSON order mixed up
The order of fields in a JSON object actually can matter. It depends on the serializer you are using. For example, when you serialize an inherited object you will get an extra JSON field called type=''. When you deserialize it the type field must come before any other JSON Field, otherwise it takes on the type of the parent.

Using jackson to traverse json tree

I'm developing a new system that talks to a third party via JSON.
One of the calls returns a huge JSON structure to represent products and rules.
I've used Jackson to convert this JSON into a tree quite easily. Now the issue is I want to be able to find nodes by 'querying' without manually traversing the whole tree.
So somewhere deep in the tree is an object which has a field called business_id. I want to return all the nodes that have this field.
Is that possible?
You can use Jackson's JsonNode class documented here:
http://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/JsonNode.html
Parse your data into a JsonNode (e.g. by ObjectMapper.readValue), then you can traverse programmatically that JSON structure as a tree.
Look at methods like: as{datatype}, find[Value|Values], is[Array|Object|{datatype}], path etc.
You could try Json Path, it lets you pick up a json node using it's xpath:
http://code.google.com/p/json-path/

Flattening an object graph to a map

I'm trying to flatten an object graph completely to a map.
Complex objects should also be flattened to the top level using "namespaces". So if the object A contains an int i, a string pid and another object B that contains a string id, the resulting Map would look like {i=1, pid="test", B.id="test1"}.
I also want to be able to reconstruct the original object from a given map.
I've searched around for libraries that do this. But I'm not quite getting what I'm looking for. I see stuff that maintains the hierarchy but nothing that completely flattens the structure.
I do see something in Spring Integration that looks like what I want to do:
http://static.springsource.org/spring-integration/api/org/springframework/integration/transformer/ObjectToMapTransformer.html#ObjectToMapTransformer%28%29
But I can't get it to work.
Any help would be appreciated.
Thanks.
The Apache BeanUtils library has a describe() method that does something similar to what I was looking for.
Another possible solution would be via the Jackson JSON library, since JSON objects are essentially key-value pairs.
Related discussions: How to convert a Java object (bean) to key-value pairs (and vice versa)?
Have you considered using Protobufs?
The json-flattener library solves exactly your problem

Categories