Extract specific value from complex JSON in java - java

I have got a valid complex json and I need to parse this json and print the values of only ak, dt and mi from this complex json in java... hope you can help me...
{
"CP": "{\"e\":{\"h\":{\"ak\":\"1c8d1d7eaa32ff3f58a882\",\"at\":\"app\"},\"c\":{\"dt\":\"MEmulator\",\"mi\":\"DD278047D56BF292F1FC16F\",\"ui\":\"m4J\/2s=\",\"av\":\"0.2\",\"pn\":\"WP\",\"pv\":\"7.10\",\"nv\":\"C# 1.1.0\",\"al\":\"en\"},\"b\":[{\"ts\":139658547,\"tz\":-400,\"s\":\"StartUpScreen\",\"et\":8,\"ev\":\"sessionStart\",\"si\":\"19477682-de55-414f-82c9-19bec331dc33\",\"tt\":{\"DaySessionStarted\":\"Tuesday\"}},{\"ts\":1319549658751,\"tz\":-400,\"s\":\"StartUpScreen\",\"et\":3,\"ev\":\"AutomaticFeedRefresh\",\"si\":\"19477682-de5ec331dc33\",\"tt\":{}},{\"ts\":1319549675609,\"tz\":-400,\"s\":\"MainScreen\",\"et\":3,\"ev\":\"MainScreen Event\",\"si\":\"19477682-de55-414f-82c9-19bec331dc33\",\"tt\":{}},{\"ts\":1319549677179,\"tz\":-400,\"s\":\"MainScreen\",\"et\":3,\"ev\":\"MainScreen Event\",\"si\":\"19477682-de55-414f-82c9-19bec331dc33\",\"tt\":{}},{\"ts\":1319549678401,\"tz\":-400,\"s\":\"MainScreen\",\"et\":3,\"ev\":\"MainScreen Event\",\"si\":\"19477682-de55-414f-82c9-19bec331dc33\",\"tt\":{}},{\"ts\":1319549679973,\"tz\":-400,\"s\":\"MainScreen\",\"et\":3,\"ev\":\"MainScreen Event\",\"si\":\"19477682-c9-19bec331dc33\",\"tt\":{}}],\"tt\":{\"OSV\":\"ME\"}}}",
"SP": {
"httpHeaders": {
"x-bluecoat-via": [
"35D3468F4D5F18"
],
"content-type": [
"application\/x-form-ur"
],
"connection": [
"Keep-Alive"
],
"host": [
"20.198.134.198:8080"
],
"accept": [
"text\/html, image\/gif, image\/jpeg, *; q=.2, *\/*; q=.2"
],
"content-length": [
"1791"
],
"user-agent": [
"Java\/1.6.0_23"
]
},
"senderIp": [
"112.101.216.113"
],
"receiveTimeStamp": "2012-06-26T06:29:36+0000"
}
}

Use json-path.
It's like xpath for JSON, and will allow you to write string queries on JSON objects.
There are a lot of examples on the project site showing possible usages, but in your case it's probably just a simple dot notation.
An example for the provided JSON:
// First extract the CP value, as its JSON-string-inside-JSON:
String cp = JsonPath.read(yourJsonString, "$.CP");
// Treat the `cp` as another JSON-string, and extract the ak value:
String ak = JsonPath.read(cp, "$.e.h.ak");
// Do the rest yourself...

You can use JsonPath to extract the value. I recommend JsonSurfer library.
<dependency>
<groupId>com.github.jsurfer</groupId>
<artifactId>jsurfer-simple</artifactId>
<version>1.2.1</version>
</dependency>
The sample code solving your problem in two steps:
1) Extract plain string from "$.CP" node.
2) Parse the "CP" string and extract value for "ak", "dt" and "mi".
JsonSurfer jsonSurfer = JsonSurfer.simple();
String cp = jsonSurfer.collectOne(new StringReader(yourString), String.class, "$.CP");
Collection<Object> result = jsonSurfer.collectAll(new StringReader(cp), "$..ak", "$..dt", "$..mi");

Like the others have suggested there are numerous libs out there that you can use (npe suggestion seems really nice). On the other hand, if you only have those simple cases and you don't really need to do anything else with JSON, maybe all you need is a regex. In essence JSON is just text, so you can do something like this:
Pattern akPattern = Pattern.compile("ak\":\"([^\"]+)");
Matcher matcher = akPattern.matcher(jsonAsString);
matcher.find();
String akValue = matcher.group(1);
System.out.println(akValue);
This prints out the value for "ak".
But again, I would only do this if I didn't have any other JSON requirements. Otherwise, go with a JSON lib.
My 2 cents.

Related

not able to create Java Object from Json having double quote in value

I have same query. My JSON is as below.
String json="{ "credentials": { "password": "Password"123", "emailAddress": "skylineadmin#gmail.com" }, "clientTimeMs": 1582006455421, "callerRole": 0 }"
key = password and value is "Password"123" it contains " (double quote).. I am not able to create a java object from this json as it is invalidated.
Gson gson = new Gson();
gson.fromJson(json, PasswordResetDetails.java);
Above code snippet is not Working.
If you are doing this for learning / testing purpose all you need to do is escaping the double quote using :
String json="{ "credentials": { "password": "Password\"123", "emailAddress": "skylineadmin#gmail.com" }, "clientTimeMs": 1582006455421, "callerRole": 0 }"
If this is a real scenario then I would like to suggest to change the source in order to make sure it provides valid JSON.
There are countless possibilities to check if your JSON is valid (JSON linting), here's one.

Json Transformation in java with high performance

I need to transform a Json into another Json according to the parameter coming as part of Rest request. This service is developed in Java. I know, Jackson API can be used easily and there are some libraries also available. But my requirement is to delivery response with new Json faster as much as possible.
If I can be given few option I can measure the performance of those.
Let's assume I have this Json in data storage:
{
"bookId": "23228232-2dfa232",
"bookName": "Json Transformation",
"bookPublisher": "Tech Publication",
"bookRating": [
{
"source": "All book rank",
"maxRating": "10",
"rating": "3.4"
},
{
"source": "Tech Books",
"maxRating": "5",
"rating": "2"
},
{
"source": "Popular",
"maxRating": "3",
"rating": "1"
}
],
"bookAuthor": [
{
"name": "Jone",
"specialities": [
"Json",
"Javascript",
"Typescript",
"nodejs"
]
},
{
"name": "Mike",
"specialities": [
"Java",
"Spring",
"ElasticSearch"
]
}
]
}
Below rest calls should have respective results from this Json:
Get only authors
/authorName/23228232-2dfa232
{
authorName: [
"Jone",
"Mike"
]
}
Get Average Rating
/popularity/23228232-2dfa232
{
rating: "1.78"
}
So, the question is how to do this kind of transformation efficiently with any available library? As I mentioned above, I can simply use any Json library in Java and transform the Json, but I am not sure, if that will be efficient.
You can try little json java library for searching json data.
JsonValue json = JsonParser.parse(stringvariablewithjsondata);
List<JsonValue> authors = json.findAll(SPM.path("bookAuthor", "name")));
List<String> ratings = json.findAllLiterals(SPM.path("bookRating", "rating")));
and compute result like
JsonArray values = JsonFactory.array();
for(JsonValue value : authors) values.add(value);
JsonObject result = JsonFactory.object().add("authorName", values);
return result.toCompactString()
You can use JSON-Java --> https://www.baeldung.com/java-org-json
Or the Google JSON, aka GSON and a few others as listed here --> https://javarevisited.blogspot.com/2016/09/top-5-json-library-in-java-JEE.html
To see popularity and use statistics, which might help you chose which ones to test first: https://www.baeldung.com/java-json
You can use GSON as it easily maps JSON with POJO classes (Especially nested ones)
For a quick reference for performance comparison,

Keep double quotes when getting element from JSONArray

I am using JsonPath to retrieve a value from a JSON file. The JSON file looks something like this:
[
{
"username": "John",
"password": {
"passwordValue": "passwordjohn",
"secret_key": "123"
}
},
{
"username": "Nick",
"password": {
"passwordValue": "XXX",
"secret_key": "ZZZ",
"other_key": "YYY"
}
}
]
The JsonPath I am using is to retrieve the password from a particular user. Example:
fun getPassword() {
val passwords: JSONArray = read(jsonFile, "\$.[?(#.name==\"John\")].password")
}
However, I found two obstacles. Firstly, I get back a net.minidev.json.JSONArray always, and the same path with appended [0] doesn't work.
Therefore, I try to get the only element from the JSONArray I get back, like this: credentials[0]. Unfortunately, this removes the double quotes in the field names, resulting in something like this:
{passwordValue: passwordjohn, secret_key: 123}
Which is impossible to work with.
I am looking for a way to get this back:
{"passwordValue": "passwordjohn", "secret_key": "123"}
What I ended up doing was to remove the [ and ] symbols from the beginning of the JSONArray after converting it to a String:
private fun JSONArray.toCredentialString(): String {
val credentialString = this.toString()
return credentialString.substring(1, credentialString.length - 1)
}
Any better solution is welcome.

Regular expression to eliminate some data from string in java?

I have a string data which has some unwanted text. I want to delete that data from string using a regular expression. The example data is given below from which I want to eliminate the key meth and its corresponding data. The regular expression I created for this purpose is "meth(S+)([\\},])" but its not working.
I used the following code to use this regular expression:
json = json.replaceAll("meth(S+)([\\},])","");
Below is the string data that is present in json :
{
data: [
{
"city": "barcelona",
"Date": "4 Apr 2014",
"Name": "A-B",
"meth": function(){
return_LANG=="en-us"?"A-T": "A-T "
},
"fo": "null",
},
{
"city": "Newyork",
"Date": "4 Apr 2014",
"Name": "B-C",
"meth": function(){
return_LANG=="en-us"?"S-E": "शक्तिपुंजएक्स."
},
"fo": "null",
}
]
}
The result I am getting is the same string as my regular expression is unable to find the matching data in String.
Please help me correcting my regex.
This should do the trick:
json = json.replaceAll("(?s)meth.*?\\},", "");
Explanation:
(?s) is for multiline regular expressions. The dot . will then also match new line characters (equal to the flag DOTALL, see Pattern#DOTALL).
.*? searches any letter in a non greedy way till it finds the },
try this
s = s.replaceAll("(?s)\"meth\":.*?},\\s+","");

Trying to extract data from JSON or JSONP using WOT api

I was using WOT(web of trust) api.In this, i am getting response in this format,
process( {
"www.google.com": {
"target": "google.com",
"0": [ 95, 84 ],
"1": [ 95, 84 ],
"2": [ 95, 84 ],
"4": [ 93, 78 ],
"categories": {
"501": 92
}
}
} )
I am very confused to extract the data string from this format of JSON. I searched a lot but could not find any way.
I want to extract from categories... means I want to save '502' value.
Problem : JSON Objects starts with "{" and ends with "}", the response you're getting is not a correct JSON Format.
Analysis : Why? you might ask, the response started with p char from process, and ends with ) char, instead of "}".
Solution : To fix the json, we will need to remove the process ( and ) string, so that the response can be parsed as JSON.
Hint : Use String.replace() method to replace the unwanted string with empty string "", more information here and here
Hope this helps, and Good Luck! ^^
Reid

Categories

Resources