Java - How to get object value in JSON array? - java

i have a JSON like example below and i'm trying to get some values, for example value of.
results.shipper.id
{
"results": [
{
"updated": false,
"notification": false,
"some_data": {
"id": 15989,
"pieces": 0,
},
"shipper": {
"updated": false,
"notification": false,
"id": 1587,
"parent": {
"updated": false
},
I'm trying to get value by this way:
String test = shipmentData.getJSONObject("shipper").getString("id");
But it always throws a exception. I think, that exception is caused because of the i am not accessing to the values via "results" array.
How can i easy access to the value what i need.
I tried find some helpers (Gson, fast-json, etc..) but it seems to be a quite complicated for using (i would like to work with JSON tree for direct access to values "on-the-fly" or access to values like to a object, it means.. Object.InnerObject.value ).
So question is how can i do it right?
Thanks for any advice.

JSON needs to be traversed in order to access id:
JSONArray results = shipmentData.getJSONArray("results");
JSONObject first = results.getJSONObject(0);
JSONObject shipper = first.getJSONObject("shipper");
Integer id = shipper.getInt("id");
Parse int to string:
String id = String.valueOf(shipper.getInt("id"));

Related

Get json object in Array based on key and value in Java

I have a Json body like the example below. I need to extract the value from a key that has another key with a specific value in an array. I am passing in a JsonNode with everything in the detail component of the message, I can easily extract from each level, however, I'm struggling with the array.
In this case, I need to extract the value of "value" (Police/Fire/Accident Report) from the object in the array which has a key/value pair of "name":"documentTitle". I understand this is a JSONArray, but I can't find a good example that shows me how to extract the values for an object in the array that contains a certain key/value pair, I don't think I can rely on getting the object in position [2] in the array as the same objects may not always be present in the additionalMetadata array.
Sample Json:
"sourceVersion": "1.0",
"eventId": "8d74b892-810a-47c3-882b-6e641fd509eb",
"clientRequestId": "b84f3a7b-03cc-4848-a1e8-3519106c6fcb",
"detail": {
"stack": "corona",
"visibilityIndicator": null,
"documentUid": "b84f3a7b-03cc-4848-a1e8-3519106c6fcb",
"additionalMetadata": [
{
"name": "lastModifiedDate",
"value": "2021-05-21T04:53:53Z"
},
{
"name": "documentName",
"value": "Police/Fire Report, 23850413, 2021-05-20 14:51:23"
},
{
"name": "documentTitle",
"value": "Police/Fire/Accident Report"
},
{
"name": "documentAuthor",
"value": "System Generated"
},
{
"name": "lastModifiedBy",
"value": "System Updated"
},
{
"name": "createdBy",
"value": "System Generated"
},
{
"name": "documentDescription",
"value": "Police/Fire Report received"
},
{
"name": "organizationCode",
"value": "Claims"
}
]
}
}```
Loop through the json array and extract the json object with name documentTitile. From that json object you can get the value
Well, either the JSON framework you're using supports this out of the box (check the documentation) or you could convert it manually to a map:
List<AdditionalMetadataEntry> additionalMetadata;
[...]
Map<String, String> additionalMetadataMap = additionalMetadata.stream().collect(Collectors.toMap(AdditionalMetadataEntry::getName, AdditionalMetadataEntry::getValue));
I was able to figure it out. I created a new node off the existing notificationBody JsonNode, then parsed through the metadata key/value pairs:
String docTitle = "";
JsonNode additionalMetadata = notificationBody.get("detail").get("additionalMetadata");
for (JsonNode node: additionalMetadata) {
String name = node.get("name").asText();
String value = node.get("value").asText();
if(name.equals("documentTitle")){
docTitle = value;
}
}

Best way to convert String to json in Android(Java)?

I am doing a statistics application using a 3rd party API. what I got from the API; json from webview with userAgent. I need to take this as a string and then convert it to json, but when I set it to the string value, I get the error "constant string too long". I found some solution but I don't think it's the best method.What is the best way to keep a big String in a variable?
Thanks for any help.
my convert code below here
Gson g = new Gson();
User user = g.fromJson(sampleJson, User.class);
Log.d("comingData",user.getGlobal_blacklist_sample());
My json has much more than user(500+) showed inside Users array (100000+ characters)
Added sample Json string below here
{
"sections": null,
"global_blacklist_sample": null,
"users": [{
"pk": 1111111111,
"username": "sample_username",
"full_name": "Sample Name :)",
"is_private": false,
"profile_pic_url": "https://sammple_pic",
"profile_pic_id": "2315322835352130707_36052201610",
"is_verified": false,
"has_anonymous_profile_picture": false,
"latest_reel_media": 0
}, {
"pk": 22222,
"username": "sample_username2",
"full_name": "Sample Name2 :)",
"is_private": false,
"profile_pic_url": "https://sammple_pic2",
"profile_pic_id": "22222222222",
"is_verified": false,
"has_anonymous_profile_picture": false,
"latest_reel_media": 0
}]
}

Get all records from JSON response

I'm still kind of new to the Rest Assured API world. I've read through as much documentation on https://github.com/rest-assured/rest-assured/wiki/Usage#example-3---complex-parsing-and-validation as I can stand.
I have a response that looks like:
{
"StatusCode": 200,
"Result": [
{
"EmployeeId": "5661631",
"PhoneTypeDescription": "Home",
"PhoneNumber": "9701234567",
},
{
"EmployeeId": "5661631",
"PhoneTypeDescription": "mobile1",
"PhoneNumber": "2531234567",
},
{
"EmployeeId": "5661631",
"PhoneTypeDescription": "mobile2",
"PhoneNumber": "8081234567",
}
]
}
I've been struggling with how to get just the first record's PhoneNumber.
String responseBody=
given()
.relaxedHTTPSValidation().contentType("application/json")
.param("api_key", api_key).
when()
.get("/api/employees/" + employeeId)
.andReturn().asString();
JsonPath jsonPath = new JsonPath(responseBody).setRoot("Result");
phoneNumber = jsonPath.getString("PhoneNumber");
I get all the phone numbers in this case:
phoneNumber = "[9701234567,2531234567,8081234567]"
How can I get just the first record? I'd rather not have to perform string operations to deal with the, "[".
Thanks
You can simply do,
JSONObject json = new JSONObject(responseBody);
phoneNumber = json.getJSONArray("Result").getJSONObject(0).getString("PhoneNumber");
Here, 0 indicates the first record in the JSON Array Result.
Because you know the index of the element you want to retrieve, you can use the following code:
JsonPath jsonPath = new JsonPath(response);
String phoneNumber = jsonPath.getString("Result[0].PhoneNumber");

How to read a specific unique json attribute in jackson

This is a json of an api. my query only asks for one language (here "en") so there is only one value in the json. And this is the only thing i want to read in the json. So i think i doesnt make sense to convert it to an object. I thought of something like:
JsonNode root = mapper.readTree(genreJson); ...
But how do i get the value without knowing the name of the attribute (in the example "12345"). This is an Id i dont have.
What do you think?
{
"entities":
{
"12345":
{
"id": "12345",
"type": "item",
"descriptions":
{
"en":
{
"language": "en",
"value": "the_value_i_want"
}
}
}
},
"success": 1
}
i thought something like
JsonNode root = mapper.readTree(genreJson); ...
try this.. may work
JsonNode value = root.path("entities").path("12345").path("descriptions").path("en").path("value");
I am not sure if its an efficient approach though

Update nested field in an index of ElasticSearch with Java API

I am using Java API for CRUD operation on elasticsearch.
I have an typewith a nested field and I want to update this field.
Here is my mapping for the type:
"enduser": {
"properties": {
"location": {
"type": "nested",
"properties":{
"point":{"type":"geo_point"}
}
}
}
}
Of course my enduser type will have other parameters.
Now I want to add this document in my nested field:
"location":{
"name": "London",
"point": "44.5, 5.2"
}
I was searching in documentation on how to update nested document but I couldn't find anything. For example I have in a string the previous JSON obect (let's call this string json). I tried the following code but seems to not working:
params.put("location", json);
client.prepareUpdate(index, ElasticSearchConstants.TYPE_END_USER,id).setScript("ctx._source.location = location").setScriptParams(params).execute().actionGet();
I have got a parsing error from elasticsearch. Anyone knows what I am doing wrong ?
You don't need the script, just update it.
UpdateRequestBuilder br = client.prepareUpdate("index", "enduser", "1");
br.setDoc("{\"location\":{ \"name\": \"london\", \"point\": \"44.5,5.2\" }}".getBytes());
br.execute();
I tried to recreate your situation and i solved it by using an other way the .setScript method.
Your updating request now would looks like :
client.prepareUpdate(index, ElasticSearchConstants.TYPE_END_USER,id).setScript("ctx._source.location =" + json).execute().actionGet()
Hope it will help you.
I am not sure which ES version you were using, but the below solution worked perfectly for me on 2.2.0. I had to store information about named entities for news articles. I guess if you wish to have multiple locations in your case, it would also suit you.
This is the nested object I wanted to update:
"entities" : [
{
"disambiguated" : {
"entitySubTypes" : [],
"disambiguatedName" : "NameX"
},
"frequency" : 1,
"entityType" : "Organization",
"quotations" : ["...", "..."],
"name" : "entityX"
},
{
"disambiguated" : {
"entitySubType" : ["a", "b" ],
"disambiguatedName" : "NameQ"
},
"frequency" : 5,
"entityType" : "secondTypeTest",
"quotations" : [ "...", "..."],
"name" : "entityY"
}
],
and this is the code:
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.index(indexName);
updateRequest.type(mappingName);
updateRequest.id(url); // docID is a url
XContentBuilder jb = XContentFactory.jsonBuilder();
jb.startObject(); // article
jb.startArray("entities"); // multiple entities
for ( /*each namedEntity*/) {
jb.startObject() // entity
.field("name", name)
.field("frequency",n)
.field("entityType", entityType)
.startObject("disambiguated") // disambiguation
.field("disambiguatedName", disambiguatedNameStr)
.field("entitySubTypes", entitySubTypeArray) // multi value field
.endObject() // disambiguation
.field("quotations", quotationsArray) // multi value field
.endObject(); // entity
}
jb.endArray(); // array of nested objects
b.endObject(); // article
updateRequest.doc(jb);
Blblblblblblbl's answer couldn't work for me atm, because scripts are not enabled in our server. I didn't try Bask's answer yet - Alcanzar's gave me a hard time, because I supposedly couldn't formulate the json string correctly that setDoc receives. I was constantly getting errors that either I am using objects instead of fields or vice versa. I also tried wrapping the json string with doc{} as indicated here, but I didn't manage to make it work. As you mentioned it is difficult to understand how to formulate a curl statement at ES's java API.
A simple way to update the arraylist and object value using Java API.
UpdateResponse update = client.prepareUpdate("indexname","type",""+id)
.addScriptParam("param1", arrayvalue)
.addScriptParam("param2", objectvalue)
.setScript("ctx._source.field1=param1;ctx._source.field2=param2").execute()
.actionGet();
arrayvalue-[
{
"text": "stackoverflow",
"datetime": "2010-07-27T05:41:52.763Z",
"obj1": {
"id": 1,
"email": "sa#gmail.com",
"name": "bass"
},
"id": 1,
}
object value -
"obj1": {
"id": 1,
"email": "sa#gmail.com",
"name": "bass"
}

Categories