Parse JSON data from string - json

I'm getting JSON data using HTTP methods in Arduino and storing in a String object. The data is:
{
"item": {
"Identity": {
"Id": "327681",
"ItemId": "64006A962B71A1E7B3A0428637DA997C.327681",
"Level": 1,
"EntityType": "64006A962B71A1E7B3A0428637DA997C",
"ItemStatus": 1
},
"Properties": {
"AssetName": "PHE-1001",
"Category": "Electrical Appliance",
"RegistrationTime": "2017-12-14Z",
"Activated": true,
"Status": "Offline",
"Manufacturer": "Philips",
"ModelNumber": "1E-S00ER11",
"SerialNumber": "YGTJGJK458545",
"sample_property": null,
"AssetLocation": null,
"AssetType": null,
"ActivationTime": "2017-12-24T05:44:38Z",
"Country": "India",
"PostalAddress": "500081",
"dummy": null,
"TotalHours": 16,
"TotalWorkingHoursFromInstallation": 38,
"TotalLifeTime": 62,
"AssetSensorDistance": null
}
}
}
Arduino code:
HTTPClient http;
http.begin("URL");
int httpCode = http.GET(); // //Send the request
if (httpCode == 200) {
String payload = http.getString();
Serial.println(payload);
}
Now I want to get only AssetName, Status and AssetSensorDistance. I have tried payload["Status"] but it prints nothing.
Can anyone help me with this? Thanks in advance.

You are missing some important bits here.
You need to include the ArduinoJson library
You need to actually parse the string into a JsonObject using JsonBuffer
The path to status would be yourRootObject["Properties"]["Status"], since it is contained inside your Properties.
See here: https://arduinojson.org/doc/decoding/
Good Luck!

Related

How to parse a jsonArray

I want to parse a JSON Array, Here is the example JSON
[
{"Vulnerabilities": [
{
"Id": "Cx35ef42d7-054c",
"CveName": "",
"Score": 9.8,
"Severity": "High",
"PublishDate": "2021-01-22T13:34:00",
"References": [
"https://github.com/mde/ejs/issues/571",
"https://github.com/mde/ejs/commit/abaee2be937236b1b8da9a1f55096c17dda905fd"
],
"Description": "ejs package before 3.1.6 is vulnerable to arbitrary code injection. The vulnerability exists due to improper input validation passed via the options parameter - the filename, compileDebug, and client option.",
"Cvss": {
"Score": 9.8,
"Severity": "High",
"AttackVector": "NETWORK",
"AttackComplexity": "LOW",
"Confidentiality": "HIGH",
"Availability": "HIGH",
"ExploitCodeMaturity": null,
"RemediationLevel": null,
"ReportConfidence": null,
"ConfidentialityRequirement": null,
"IntegrityRequirement": null,
"AvailabilityRequirement": null,
"Version": 3.0
},
"Recommendations": null,
"PackageId": "Npm-ejs-2.7.4",
"FixResolutionText": "3.1.7",
"IsIgnored": true,
"ExploitableMethods": [],
"Cwe": "CWE-94",
"IsViolatingPolicy": true,
"IsNewInRiskReport": false,
"Type": "Regular"
},
{
"Id": "CVE-2022-29078",
"CveName": "CVE-2022-29078",
"Score": 9.8,
"Severity": "High",
"PublishDate": "2022-04-25T15:15:00",
"References": [
"https://github.com/advisories/GHSA-phwq-j96m-2c2q",
"https://eslam.io/posts/ejs-server-side-template-injection-rce/",
"https://github.com/mde/ejs/commit/61b6616fd34ff4d21c38fe1dbaf2b3aa936bb749",
"https://github.com/mde/ejs/issues/451",
"https://github.com/mde/ejs/pull/601"
],
"Description": "The ejs (aka Embedded JavaScript templates) package up to 3.1.6 for Node.js allows server-side template injection in settings[view options][outputFunctionName]. This is parsed as an internal option, and overwrites the outputFunctionName option with an arbitrary OS command (which is executed upon template compilation).",
"Cvss": {
"Score": 9.8,
"Severity": "High",
"AttackVector": "NETWORK",
"AttackComplexity": "LOW",
"Confidentiality": "HIGH",
"Availability": "HIGH",
"ExploitCodeMaturity": null,
"RemediationLevel": null,
"ReportConfidence": null,
"ConfidentialityRequirement": null,
"IntegrityRequirement": null,
"AvailabilityRequirement": null,
"Version": 3.0
},
"Recommendations": null,
"PackageId": "Npm-ejs-2.7.4",
"FixResolutionText": "3.1.7",
"IsIgnored": true,
"ExploitableMethods": [],
"Cwe": "CWE-74",
"IsViolatingPolicy": true,
"IsNewInRiskReport": false,
"Type": "Regular"
}
}
]
I want to parse the JSON array and get the value of Ids in a list. If it was a JSON response my code would be
id = response.getBody.jsonPath.getList("vulnerabilities.Id");
but it is a JSON file. I have to read the file and then parse the JSON to fetch value of id into a List. Can someone please help?
(Assuming you're doing it in Java)
You do the following (using Google gson):
Gson gson = new Gson();
JsonReader reader = new JsonReader(new FileReader(file_path));
After this - there are two approaches,
Either,
Create a POJO that matches your Objects (Preferred)
ResponseHolder response = gson.fromJson(reader, ResponseHolder.class);
In your case, as it's an array
List<ResponseHolder> responses = gson.fromJson(yourJson, new TypeToken<List<ResponseHolder>>() {}.getType());
Then extract the required field from your object.
//Or loop on each-element based on your use case
responses.get(0).getVulnerabilities().get(0).getId()
OR
Use JsonArray/JsonObject class
JsonArray responses = gson.fromJson(reader, JsonArray.class);
for (JsonElement response : responses) {
JsonObject item = response.getAsJsonObject();
JsonArray vulnerabilities = item.get("vulnerabilities").getAsJsonArray();
//Or Loop
Strring idOfFirst = vulnerabilities.get(0).getAsJsonObject("id").getAsString();
}

How to create a dynamic request in Jmeter

I have a response from an API
[{
"userSourceMeta": {
"userId": "sss#gmail.com",
"source": "BOX",
"organisationId": 1,
"emailId": "sss#gmail.com",
"sourceUserId": "15548727375",
"accessToken": null,
"refreshToken": null,
"lastCursorPosition": null,
"lastAccessTime": 1626025027228,
"name": "John",
"createdAt": 1622444279509
},
"connectionStatus": null}, {
"userSourceMeta": {
"userId": "test#gmail.com",
"source": "ONEDRIVE",
"organisationId": 1,
"emailId": "sss#outlook.com",
"sourceUserId": "3969b928a1a28f34",
"accessToken": null,
"refreshToken": null,
"lastCursorPosition": null,
"lastAccessTime": 1626025027228,
"name": "sss ddd",
"createdAt": 1624262423446
},
"connectionStatus": null}]
I have to use two parameters in the successive request(source,sourceUserId) . This is a dynamic request it can be varied 3, 4,5 ..etc.
Next API request.
{
"Answer": "My name is xyz",
"queryChannel": "WEB_APP",
"timeZone": "Asia/Calcutta",
"sourceFilterInfo": [{
"sourceUserId": "15548727375",
"source": "BOX"
}, {
"sourceUserId": "3969b928a1a28f34",
"source": "ONEDRIVE"
}],
"contextIds": []
}
Please provide a solution to send a dynamic request with the previous API response.
I used regular expression extractor to store values. But how to send it in a request.
Add JSR223 PostProcessor as a child of the request which returns the above JSON and put the following code into "Script" area:
def response = new groovy.json.JsonSlurper().parse(prev.getResponseData())
def sourceFilterInfo = []
response.each { entry ->
def user = [sourceUserId: entry['userSourceMeta'].sourceUserId, source: entry['userSourceMeta'].source]
sourceFilterInfo.add(user)
}
def payload = [:]
payload.put('Answer', 'My name is xyz')
payload.put('queryChannel', 'WEB_APP')
payload.put('timeZone', 'Asia/Calcutta')
payload.put('sourceFilterInfo', sourceFilterInfo)
payload.put('contextIds', [])
vars.put('payload', new groovy.json.JsonBuilder(payload).toPrettyString())
That's it, now you should be able to refer the generated request as ${payload} where required
More information:
Apache Groovy - Parsing and producing JSON
Apache Groovy - Why and How You Should Use It

Error on flutter : type 'List<dynamic>' is not a subtype of type 'String'

I have this Json. I want to map my json data. But i get some error.
{
"Id": 0,
"Product_Id": 0,
"Quantity": 0,
"User_Id": "a49a10d2-fc3f-477a-b087-5b0d07545964",
"Active": false,
"CartProducts": null,
"Products": [
{
"Id": 116,
"Shop_Id": 1,
"Offer": 0.0,
"Quantity": 1,
"Price": 100.0,
"Category_Id": 0,
"Description": null,
"Name": "Lacoste Product",
"Active": false,
"Size": "small",
"Color": "black",
"Is_External_Product": true,
"External_Link": "https://www.lacoste.com.tr/urun/kadin-kirmizi-polo-pf0504-007-4/",
"Currency": null,
"ProductImages": null
}
]
}
I am decoding Json here
if(jsonObject['Products']!=null){
productItems = ProductItem.getListFromJson(jsonObject['Products']);
}
static List<ProductItem> getListFromJson(List<dynamic> jsonArray) {
log("getListFromJson");
List<ProductItem> list = [];
for (int i = 0; i < jsonArray.length; i++) {
list.add(ProductItem.fromJson(jsonArray[i]));
}
return list;
}
But i get this error. "[log] type 'List' is not a subtype of type 'String'"
You are trying to assign a value of type String to the product items array. There might be a possibility one of your responses is returning a String and you are expecting an array. Please inspect the response.
It's a JSON parsing issue, and it might not directly related to "Products" as being a list or string.
So instead, for better diagnosing this error, or other error on the future, you could need to enable the dart debugger, while checking the "uncaught exception" option, which will guide you to the broken type casting issue.

SwiftyJSON not working with WebSocket message

I have a socket response that is this:
{"op":0,"d":{"author":{"id":"6699457769390473216","name":"Test","verified":false},"unixTime":1597277057132,"id":"6699465549836976128","group":"64632423765273287342","content":"Yo","_id":"5f34838198980c0023fa49e3"},"t":"MESSAGE"}
and I need to access the "d" object, I've tried doing
print(JSON(data)["d"])
and it just Returns null every time.
If data is of type String, you are probably using the wrong init method to initialize the JSON object. Try using init(parseJSON:) like this:
let jsonString = """
{
"op": 0,
"d": {
"author": {
"id": "6699457769390473216",
"name": "Test",
"verified": false
},
"unixTime": 1597277057132,
"id": "6699465549836976128",
"group": "64632423765273287342",
"content": "Yo",
"_id": "5f34838198980c0023fa49e3"
},
"t": "MESSAGE"
}
"""
let json = JSON(parseJSON: jsonString)
print(json["d"])

ember data custom serializer for a json

I have a Session object I want to model in Ember data. (actually display sessions but it's the same)
The JSON from the server looks like this (cannot be changed):
{
"metadata": {
"page": 1,
"page_size": 100,
"total_num_objects": 7,
"total_num_pages": 1
},
"result": [
{
"api_path": "/rest/sessions/2",
"end_time": 1412687629.42063,
"hostname": "127.0.0.1",
"id": 2,
"logical_id": "c6656738-4e23-11e4-9017-685b35b63131_0",
"product_name": null,
"product_revision": null,
"product_version": null,
"start_time": 1412687629.26851,
"status": "SUCCESS",
"type": "session",
"user_name": null
},
{
"api_path": "/rest/sessions/3",
"end_time": 1412688377.15329,
"hostname": "127.0.0.1",
"id": 3,
"logical_id": "84707366-4e25-11e4-a659-685b35b63131_0",
"product_name": null,
"product_revision": null,
"product_version": null,
"start_time": 1412688377.11507,
"status": "SUCCESS",
"type": "session",
"user_name": null
},
...
I realize I need to write a custom RESTSerializer but I can't figure out what do I need to do in order go get rid of metadata + make ember realize that result is actually a session.
Side question:
Can I make the DS.Model.extend attributes like what I get from the API or do I must use CamelCase and use normalizeHash
You'd probably need to do something like this:
App.SessionSerializer = DS.RESTSerializer.extend({
normalizePayload: function(payload) {
return {
sessions: payload.result
};
}
});
See: http://emberjs.com/api/data/classes/DS.RESTSerializer.html#method_normalizePayload
Regarding your other issue, look at DS.ActiveModelAdapter / ActiveModelSerializer. ActiveModelSerializer handles the underscore convention in the JSON.