I'm parsing dynamic nested json using gson and Retrofit in Android. I want to exclude null/empty values before I add it to the list.
I've tried the following methods but none of them seem to work:
// retMap.values().removeIf(Objects::isNull);
// Collection<POJOContent> values = retMap.values();
// while (values.remove(null)) {}
//list.removeAll(Arrays.asList(""));
CustomDeserialiser.java
public class CustomDeserializer implements JsonDeserializer<MyContentWrapper> {
private final String abc_key = "abc";
#Override
public MyContentWrapper deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
MyContentWrapper abc = new MyContentWrapper();
JsonObject object = json.getAsJsonObject().getAsJsonObject(abc_key);
List<POJOContent> list = new ArrayList<POJOContent>();
System.out.println("New Data: "+object);
for (Map.Entry<String, JsonElement> set : object.entrySet()) {
System.out.println("LIST " + set);
JsonObject nextObject = object.getAsJsonObject().getAsJsonObject(set.getKey());
Map<String, POJOContent> retMap = new Gson().fromJson(nextObject, new TypeToken<LinkedHashMap<String, POJOContent>>() {
}.getType());
// retMap.values().removeIf(Objects::isNull);
// Collection<POJOContent> values = retMap.values();
// while (values.remove(null)) {}
list.addAll(retMap.values());
//list.removeAll(Arrays.asList(""));
}
abc.abc = list;
return abc;
}
POJOContent.java
public class POJOContent {
#SerializedName("ab")
public String content;
#SerializedName("id")
public String id;
#SerializedName("key")
public String key;
#Override
public String toString() {
return content;
}
//getters and setters
}
MyContentWrapper.java
public class MyContentWrapper {
public List<POJOContent> abc;
}
JSON:
{
"abc": {
"1": {
"1": {
"ab": "some content",
"id": "240",
"key": "value"
},
"2": {
"ab": "some content",
"id": "240",
"key": "value"
},
"3": {
"ab": "some content",
"id": "240",
"key": "value"
}
},
"2": {
"1": {
"ab": "some content",
"id": "241",
"key": "value"
},
"2": {
"ab": "some content",
"id": "241",
"key": "value"
},
"3": {
"ab": "some content",
"id": "241",
"key": "value"
}
},
"3": {
"1": {
"ab": "",
"id": "252",
"key": "value"
},
"2": {
"ab": "some content",
"id": "252",
"key": "value"
},
"3": {
"ab": "",
"id": "252",
"key": "value"
}
}
}
}
Basically, I want to skip the objects whose "ab" value is empty and NOT add them to the list (the other keys are irrelevant if the "ab" value is empty). To clarify, if the parent object has any child object with "ab" key empty value, the child object should be excluded. If the parent object has all children whose "ab" key has empty values, it should exclude the parent object.
Am I missing something? Would appreciate some help.
EDIT:: Expected JSON:
{
"abc": {
"1": {
"1": {
"ab": "some content",
"id": "240",
"key": "value"
},
"2": {
"ab": "some content",
"id": "240",
"key": "value"
},
"3": {
"ab": "some content",
"id": "240",
"key": "value"
}
},
"2": {
"1": {
"ab": "some content",
"id": "241",
"key": "value"
},
"2": {
"ab": "some content",
"id": "241",
"key": "value"
},
"3": {
"ab": "some content",
"id": "241",
"key": "value"
}
},
"3": {
"2": {
"ab": "some content",
"id": "252",
"key": "value"
}
}
}
}
UPDATE 2:
This is the response I'm getting after changing List to Maps:
Callback<MyContentWrapper> myCallback = new Callback<MyContentWrapper>() {
#Override
public void onResponse(Call<MyContentWrapper> call, Response<MyContentWrapper> response) {
if (response.isSuccessful()) {
Log.d("Callback", " Message: " + response.raw());
Log.d("Callback", " Message: " + response.body().abc.values());
still showing empty brackets here --->
//Log.d = Message: [{1=1. some content, 1=2. some content, 1=3. some content}, {}]
} else {
Log.d("Callback", "Code: " + response.code() + " Message: " + response.message());
}
}
#Override
public void onFailure(Call<MyContentWrapper> call, Throwable t) {
t.printStackTrace();
}
};
Just for context, this is the JSON response to above the callback:
{
"abc": {
"1": {
"1": {
"ab": "some content",
"id": "240",
"key": "value"
},
"2": {
"ab": "some content",
"id": "240",
"key": "value"
},
"3": {
"ab": "some content",
"id": "240",
"key": "value"
}
},
"2": {
"1": {
"ab": "",
"id": "241",
"key": "value"
},
"2": {
"ab": "",
"id": "241",
"key": "value"
},
"3": {
"ab": "",
"id": "241",
"key": "value"
}
}
}
}
First of all your MyContentWrapper is wrong. It is not a List according to your JSON. It should be map of maps so something like:
public class MyContentWrapper {
public Map<Integer, Map<Integer, POJOContent>> abc;
}
Now, you could write some complex deserializer for this kind of structure but there is also an another way to do it. Namely, if you declare helper Map like:
#SuppressWarnings("serial")
public class MyMap extends HashMap<Integer, POJOContent> {
#Override
public POJOContent put(Integer key, POJOContent value) {
if(null==value.getContent() || value.getContent().isBlank()) {
return null;
}
// Added only if content = "ab" is not blank.
return super.put(key, value);
}
}
and then the tuned MyContentWrapper:
public class MyContentWrapper {
public Map<Integer, MyMap> abc;
}
Then it is only:
MyContentWrapper mcw = new Gson().fromJson(JSON, MyContentWrapper.class);
Related
I have a response which contains values which I need.
private void getDataFromDistanceMatrixToSaveAndAddToList(
GRATestDataImport place, String response) {
JSONObject responseAsJson = new JSONObject(response).getJSONArray("rows")
.getJSONObject(0)
.getJSONArray("elements")
.getJSONObject(0);
}
'response' in params includes:
{
"destination": [
"54.375,18.59"
],
"origin": [
"54.001,21.721"
],
"rows": [
{
"elements": [
{
"distance": {
"text": "304.4 km",
"value": 304403
},
"duration": {
"text": "3 h 53 min",
"value": 14003
},
"status": "OK"
}
]
}
],
"status": "OK"
}
value: 'responseAsJson' in my method is:
{
"duration": {
"text": "3 h 53 min",
"value": 14003
},
"distance": {
"text": "304.4 km",
"value": 304403
},
"status": "OK"
}
How can I get value from the duration and the distance ?
you'll just have to navigate along
int duration = responseAsJson.getJSONObject("duration").getInt("value");
int distance = responseAsJson.getJSONObject("distance").getInt("value");
public class YourResponse
{
public string duration { get; set; }
public string distance { get; set; }
}
YourResponse response = JsonSerializer.Deserialize<YourResponse>(result);
I have a response received from sharepoint.
{
"d": {
"query": {
"SecondaryQueryResults": {
"__metadata": {
"type": "Collection(Microsoft.Office.Server.Search.REST.QueryResult)"
},
"results": []
},
"SpellingSuggestion": "",
"TriggeredRules": {
"__metadata": {
"type": "Collection(Edm.Guid)"
},
"results": ["e0205660-4971-4574-aa40-af6b4383cadd"]
},
"ElapsedTime": 224,
"__metadata": {
"type": "Microsoft.Office.Server.Search.REST.SearchResult"
},
"Properties": {
"__metadata": {
"type": "Collection(SP.KeyValue)"
},
"results": [{
"ValueType": "Edm.Int32",
"Value": "10",
"Key": "RowLimit"
}, {
"ValueType": "Edm.Guid",
"Value": "8413cd39-2156-4e00-b54d-11efd9abdb49",
"Key": "SourceId"
}, {
"ValueType": "Edm.Guid",
"Value": "7bc4ba9e-80ff-7000-58cf-f7ac556d1e34",
"Key": "CorrelationId"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "WasGroupRestricted"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "IsPartial"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "HasParseException"
}, {
"ValueType": "Edm.String",
"Value": "en",
"Key": "WordBreakerLanguage"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "IsPartialUpnDocIdMapping"
}, {
"ValueType": "Edm.Boolean",
"Value": "true",
"Key": "EnableInterleaving"
}, {
"ValueType": "Edm.Boolean",
"Value": "false",
"Key": "IsMissingUnifiedGroups"
}, {
"ValueType": "Edm.String",
"Value": "i62456",
"Key": "Constellation"
}, {
"ValueType": "Edm.String",
"Value": "<Query Culture=\"en-US\" EnableStemming=\"True\" EnablePhonetic=\"False\" EnableNicknames=\"False\" IgnoreAllNoiseQuery=\"True\" SummaryLength=\"180\" MaxSnippetLength=\"180\" DesiredSnippetLength=\"90\" KeywordInclusion=\"0\" QueryText=\"59055305\" QueryTemplate=\"\" TrimDuplicates=\"True\" Site=\"e297bd2b-597a-4f54-8509-e2febb91b869\" Web=\"d42ff0d1-883b-4545-ab6a-97b0401025d4\" KeywordType=\"True\" HiddenConstraints=\"\" \/>",
"Key": "SerializedQuery"
}]
},
"PrimaryQueryResult": {
"RefinementResults": null,
"SpecialTermResults": null,
"QueryId": "0585a5f1-89bc-43c1-b736-e163b4d7c1dd",
"QueryRuleId": "00000000-0000-0000-0000-000000000000",
"CustomResults": {
"__metadata": {
"type": "Collection(Microsoft.Office.Server.Search.REST.CustomResult)"
},
"results": []
},
"__metadata": {
"type": "Microsoft.Office.Server.Search.REST.QueryResult"
},
"RelevantResults": {
"Table": {
"__metadata": {
"type": "SP.SimpleDataTable"
},
"Rows": {
"results": [{
"__metadata": {
"type": "SP.SimpleDataRow"
},
"Cells": {
"results": [{
"ValueType": "Edm.Double",
"Value": "26.8860855102549",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Rank"
}, {
"ValueType": "Edm.Int64",
"Value": "17594532057853",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "DocId"
}, {
"ValueType": "Edm.Int64",
"Value": "17594531057253",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "WorkId"
}, {
"ValueType": "Edm.String",
"Value": "Customer Request Filling",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Title"
}, {
"ValueType": "Edm.String",
"Value": "Technology Services;svc ECMWise",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Author"
}, {
"ValueType": "Edm.Int64",
"Value": "97182",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Size"
}, {
"ValueType": "Edm.String",
"Value": "https:\/\/xxxxxx.sharepoint.com\/sites\/news\/CUST\/Forms\/Appeals\/Customer Reader.pdf",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Path"
}, {
"ValueType": "Null",
"Value": null,
"__metadata": {
"type": "SP.KeyValue"
},
....
What I am trying to get is the "Path" of "Value" string of that pdf as a snapshot from below (part of section from what was above)
{
"ValueType": "Edm.String",
"Value": "https:\/\/xxxxxx.sharepoint.com\/sites\/news\/CUST\/Forms\/Appeals\/Customer Reader.pdf",
"__metadata": {
"type": "SP.KeyValue"
},
"Key": "Path"
}
I have tried to use JSONObject to parse it like this.
JSONObject jsonObject = (JSONObject) parser.parse(new InputStreamReader((httpConn.getInputStream())));
JSONObject folder = (JSONObject)jsonObject.get("d");
JSONObject query = (JSONObject) folder.get("query");
JSONObject properties = (JSONObject) query.get("PrimaryQueryResult");
JSONObject result = (JSONObject) properties.get("RelevantResults");
JSONObject table = (JSONObject) result.get("Table");
JSONObject rows = (JSONObject) table.get("Rows");
....
I was wondering if there is a easier way to do this or what if one of the key is not populated. It would throw null pointer exception so is there a way just to find a key directly inside of this long nested json and how do I get the field "Key" from the json array of the "Cells"
You should consider using a JSON serializer such as Jackson or GSON.
If the underlying JSON response structure will be the same for each call, even if it has missing keys, you can create your own POJO using something like JSONSchema2POJO. This will generate a POJO with Jackson or GSON annotations using a JSON string that you provide. Here's an example using a snippet of your JSON string:
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("ValueType")
#Expose
private String valueType;
#SerializedName("Value")
#Expose
private String value;
#SerializedName("__metadata")
#Expose
private Metadata metadata;
#SerializedName("Key")
#Expose
private String key;
public String getValueType() {
return valueType;
}
public void setValueType(String valueType) {
this.valueType = valueType;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Metadata getMetadata() {
return metadata;
}
public void setMetadata(Metadata metadata) {
this.metadata = metadata;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
-----------------------------------com.example.Metadata.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Metadata {
#SerializedName("type")
#Expose
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
This is standard practice when consuming JSON in Java and it allows keys/values to be null when the object is serialized without breaking your code.
If the JSON structure is completely unpredictable, GSON allows you to create Generic types or you can take it a step further and write custom serializers. Jackson likely has similar functionality but I'm only versed in GSON.
You could use quick-json (enter link description here) and have something like this (rapid version not optimized) :
public class Go {
public static void main(String[] args) {
try {
List<String> pdf_list = new ArrayList<>();
JsonParserFactory factory= JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson("/54424034/sharepoint.json", "UTF-8");
//jsonMap.get("d/query/PrimaryQueryResult/RelevantResults/Table/Rows/results");
Map d = (Map) jsonMap.get("d");
Map query = (Map) d.get("query");
Map primaryQueryResult = (Map) query.get("PrimaryQueryResult");
Map relevantResults = (Map) primaryQueryResult.get("RelevantResults");
Map table = (Map) relevantResults.get("Table");
Map rows = (Map) table.get("Rows");
List<Map> results_rows = (ArrayList) rows.get("results");
for (Map result_row : results_rows) {
Map cells = (Map) result_row.get("Cells");
List<Map> results_cells = (ArrayList) cells.get("results");
for (Map result_cell : results_cells) {
String key = (String) result_cell.get("Key");
if ("Path".equalsIgnoreCase(key)) {
pdf_list.add((String) result_cell.get("Value"));
}
}
}
System.out.println(pdf_list);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
It just parses your Json and add all pdf path into a List
Below is the JSON, in which I need to parse the value of:
"primaryInvolvedParty":
{
}
The response is XML, hence it is converted into JSON, so that I can parse it easily.
Converting XML to JSON using:
String messageBody = actualResult.get("StatusMessage");
JSONObject xmlconvertedjson=XML.toJSONObject(messageBody);
JsonElement jelement = new
JsonParser().parse(xmlconvertedjson.toString());
But I am looking for the generic function where I can fetch the key-value for given attribute, for ex: customerScore.scoreResult= Accept,
Please help as I am new to Rest Assured parsing.
JSON:
{
"soap:Envelope": {
"soap:Header": "",
"xmlns:soap": "http://schemas.xmlsoap.org/soap/envelope/",
"soap:Body": {
"ns2:offerProductArrangementResponse": {
"xmlns:ns2": "http://LIB_SIM_SalesProcessManagement/IA_OfferProductArrangement",
"response": {
"productArrangement": {
"arrangementId": "317076",
"offeredProducts": {
"externalSystemProductIdentifier": [
{
"productIdentifier": "901",
"systemCode": "00107"
},
{
"productIdentifier": "201",
"systemCode": "10107"
},
{
"productIdentifier": "P_CLASSIC",
"systemCode": "00010"
},
{
"productIdentifier": "0071306000",
"systemCode": "00004"
},
{
"productIdentifier": "0071776000",
"systemCode": "00004"
}
],
"productIdentifier": "92",
"productoffer": {
"offerType": "2001"
},
"associatedFamily": {
"extsysprodfamilyidentifier": {
"productFamilyIdentifier": "502"
}
},
"productoptions": [
{
"optionsDescription": "Correspondence Default",
"optionsName": "Correspondence Default",
"optionsType": "CorrespDef",
"optionsValue": "Paper",
"optionsCode": "3521"
},
{
"optionsDescription": "Correspondence Option",
"optionsName": "Correspondence Option",
"optionsType": "CorrespOp",
"optionsValue": "Choice",
"optionsCode": "2944"
},
{
"optionsDescription": "Debit Card Funding",
"optionsName": "Debit Card Funding",
"optionsType": "DCF",
"optionsValue": "N",
"optionsCode": "3943"
},
{
"optionsDescription": "Product Priority",
"optionsName": "Product priority",
"optionsType": "PrdPriority",
"optionsValue": "5",
"optionsCode": "2658"
},
{
"optionsDescription": "Upsell Display Value",
"optionsName": "Upsell Display Value",
"optionsType": "UPSellDispval",
"optionsValue": "0",
"optionsCode": "2659"
},
{
"optionsDescription": "Account Switching",
"optionsName": "Account Switching",
"optionsType": "AccSwitching",
"optionsValue": "Y",
"optionsCode": "2662"
},
{
"optionsDescription": "VERDE PRODUCT ID",
"optionsName": "VERDE PRODUCT ID",
"optionsType": "VerdeProdId",
"optionsValue": "20051",
"optionsCode": "4523"
},
{
"optionsDescription": "Vantage Product Id for Verde",
"optionsName": "Vantage Product Id for Verde",
"optionsType": "VantProdIDVer",
"optionsValue": "20055",
"optionsCode": "4963"
},
{
"optionsDescription": "isVantage",
"optionsName": "isVantage",
"optionsType": "isVantage",
"optionsValue": "No",
"optionsCode": "6659"
},
{
"optionsDescription": "Overdraft Offer Flag",
"optionsName": "Overdraft Offer Flag",
"optionsType": "OD_Offer_Flag",
"optionsValue": "Y",
"optionsCode": "6905"
},
{
"optionsDescription": "Make_It_Joint",
"optionsName": "Make_It_Joint",
"optionsType": "MkItJoint",
"optionsValue": "1",
"optionsCode": "6975"
},
{
"optionsDescription": "Survey",
"optionsName": "Survey",
"optionsType": "Survey",
"optionsValue": "Y",
"optionsCode": "7288"
},
{
"optionsDescription": "Statement Option",
"optionsName": "Statement Option",
"optionsType": "StateOp",
"optionsValue": "Choice",
"optionsCode": "1099"
},
{
"optionsDescription": "Statement Default",
"optionsName": "Statement Default",
"optionsType": "StateDef",
"optionsValue": "Paper",
"optionsCode": "1770"
},
{
"optionsDescription": "Tariff",
"optionsName": "Tariff",
"optionsType": "TRF",
"optionsValue": "1",
"optionsCode": "2663"
}
],
"productName": "Classic Account"
},
"applicationType": "10001",
"xsi:type": "ns7:DepositArrangement",
"isOverdraftRequired": "true",
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"xmlns:ns7": "http://LIB_SIM_BO/BusinessObjects",
"primaryInvolvedParty": {
"auditData": [
{
"auditTime": "132551",
"auditType": "PARTY_EVIDENCE",
"auditDate": "12012018"
},
{
"auditTime": "132551",
"auditType": "ADDRESS_EVIDENCE",
"auditDate": "12012018"
},
{
"auditTime": "132551",
"auditType": "ADDRESS",
"auditDate": "12012018"
}
],
"isAuthCustomer": "false",
"cidPersID": "+00554133625",
"customerSegment": "3",
"individualIdentifier": "249894",
"newCustomerIndicator": "true",
"customerIdentifier": "2012794088",
"customerScore": [
{
"scoreResult": "ACCEPT",
"assessmentType": "EIDV",
"decisionText": "001",
"decisionCode": "I",
"assessmentEvidence": {
"addressStrength": "900",
"evidenceIdentifier": "4696198HL890678339009003211586646102",
"identityStrength": "900"
}
},
{
"scoreResult": "1",
"assessmentType": "ASM",
"referralCode": [
{
"code": "601",
"description": "Accept."
},
{
"code": "601",
"description": "Accept."
}
],
"scoreIdentifier": "647448142"
}
]
},
"arrangementType": "CA",
"applicationStatus": "1002",
"associatedProduct": {},
"conditions": [
{
"result": "No",
"name": "INTEND_TO_SWITCH"
},
{
"result": "true",
"name": "INTEND_TO_OVERDRAFT"
},
{
"result": "Y",
"name": "CHECK_BOOK_OFFERED_FLAG"
},
{
"result": "20",
"name": "DEBIT_CARD_RISK_CODE"
},
{
"result": "4",
"name": "OVERDRAFT_RISK_CODE"
}
],
"overdraftDetails": {
"amount": {
"amount": "3001"
}
}
},
"header": {
"interactionId": "ucoGI58OmuY0bfYXx2iLqta",
"LloydsHeaders": [
{
"prefix": "ns4",
"name": "ServiceRequest",
"nameSpace": "http://www.lloydstsb.com/Schema/Infrastructure/SOAP",
"value": {
"ns5:From": "10.245.211.214",
"xsi:type": "ns5:ServiceRequest",
"ns5:Action": "offerProductArrangement",
"ns5:ServiceName": "offerProductArrangement",
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"ns5:mustReturn": "false",
"ns5:MessageId": "ucoGI58OmuY0bfYXx2iLqta"
}
},
{
"prefix": "ns4",
"name": "ContactPoint",
"nameSpace": "http://www.lloydstsb.com/Schema/Infrastructure/SOAP",
"value": {
"ns5:OperatorType": "Customer",
"ns5:ContactPointId": "0000777505",
"ns5:ApplicationId": "AL07618",
"ns5:InitialOriginatorId": "10.245.224.125",
"xsi:type": "ns5:ContactPoint",
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"ns5:mustReturn": "false",
"ns5:InitialOriginatorType": "Browser",
"ns5:ContactPointType": "003"
}
},
{
"prefix": "ns5",
"name": "bapiInformation",
"nameSpace": "http://www.lloydstsb.com/Schema/Enterprise/LCSM",
"value": {
"ns4:BAPIId": "B001",
"xsi:type": "ns4:bapiInformation",
"ns4:BAPIOperationalVariables": {
"ns4:bForceHostCall": "false",
"ns4:bBatchRetry": "false",
"ns4:bPopulateCache": "false"
},
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"ns4:BAPIHeader": {
"ns4:acceptLanguage": {
"xsi:nil": "true"
},
"ns4:inboxidClient": "GX",
"ns4:cctmauthcd": {
"xsi:nil": "true"
},
"ns4:encVerNo": {
"xsi:nil": "true"
},
"ns4:sessionid": "ucoGI58OmuY0bfYXx2iLqta",
"ns4:useridAuthor": "UNAUTHSALE",
"ns4:userAgent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36",
"ns4:chanidObo": {
"xsi:nil": "true"
},
"ns4:stpartyObo": {
"ns4:ocisid": "737704834",
"ns4:partyid": "+00263174828",
"ns4:host": "I"
},
"ns4:chanid": "IBL",
"ns4:ipAddressCaller": {
"xsi:nil": "true"
},
"ns4:chanctxt": "1",
"ns4:callerlineid": {
"xsi:nil": "true"
},
"ns4:chansecmode": "PWD"
}
}
},
{
"prefix": "lgsm",
"name": "Security",
"nameSpace": "http://LB_GBO_Sales/Messages",
"value": {
"mustReturn": "false",
"ns3:UsernameToken": {
"ns3:Username": "UNAUTHSALE",
"ns3:UNPMechanismType": "NTLM",
"Id": "LloydsTSBSecurityToken",
"ns3:UserType": "013"
},
"xsi:type": "ns3:SecurityHeaderType",
"xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance"
}
}
],
"businessTransaction": "OfferProductArrangement",
"channelId": "LTB"
}
},
"xmlns:ns5": "http://www.lloydstsb.com/Schema/Infrastructure/SOAP",
"xmlns:ns3": "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"xmlns:ns4": "http://www.lloydstsb.com/Schema/Enterprise/LCSM"
}
}
}
}
I think you can build your function using XPath or JsonPath as base of your solution
The specified json response is nested. Through method chaining technique the code can be written as follows:
String messageBody = actualResult.get("StatusMessage");
JSONObject xmlconvertedjson=XML.toJSONObject(messageBody);
JsonElement primaryInvolvedParty = xmlconvertedjson.get("soap:Envelope").getAsJsonObject().get("soap:Body").getAsJsonObject().get("ns2:offerProductArrangementResponse").getAsJsonObject().get("response").getAsJsonObject().get("productArrangement").getAsJsonObject().get("primaryInvolvedParty");
For readability this code can be written as follows:
String messageBody = actualResult.get("StatusMessage");
JSONObject xmlconvertedjson = XML.toJSONObject(messageBody);
JsonElement soapEnvelope = xmlconvertedjson.getAsJsonObject().get("soap:Envelope");
JsonElement soapBody = soapEnvelope.getAsJsonObject().get("soap:Body");
JsonElement ns2offerProductArrangementResponse = soapBody.getAsJsonObject().get("ns2:offerProductArrangementResponse");
JsonElement response = ns2offerProductArrangementResponse.getAsJsonObject().get("response");
JsonElement productArrangement = response.getAsJsonObject().get("productArrangement");
JsonElement primaryInvolvedParty = productArrangement.getAsJsonObject().get("primaryInvolvedParty");
#Nithin Dhanyavadagalu
Thanks for the solution.Below code worked , but looking for some generic code.
String messageBody = actualResult.get("StatusMessage");
JSONObject xmlconvertedjson=XML.toJSONObject(messageBody);
JsonElement jelement = new JsonParser().parse(xmlconvertedjson.toString());
JsonObject jobject = jelement.getAsJsonObject();
System.out.println("Parsed json object"+jobject);
JsonElement soapEnvelope = jobject.get("soap:Envelope").getAsJsonObject().get("soap:Body").getAsJsonObject().get("ns2:offerProductArrangementResponse").getAsJsonObject().get("response").getAsJsonObject().get("productArrangement");
JsonElement primaryInvolvedParty = soapEnvelope.getAsJsonObject().get("primaryInvolvedParty");
JsonElement audit = primaryInvolvedParty.getAsJsonObject().get("customerScore");
System.out.println("Primaryparty:"+audit);
JsonArray jsonarray = audit.getAsJsonArray();
System.out.println( jsonarray.get(0).getAsJsonObject().get("scoreResult"));
System.out.println( jsonarray.get(0).getAsJsonObject().get("assessmentType"));
System.out.println( jsonarray.get(1).getAsJsonObject().get("assessmentType"));
I am going to get facebook read_books
The file is in this format:
{
"data": [
{
"id": "270170479804513",
"from": {
"name": "L I",
"id": "1000022"
},
"start_time": "2014-01-22T09:31:00+0000",
"publish_time": "2014-01-22T09:31:00+0000",
"application": {
"name": "Books",
"id": "174275722710475"
},
"data": {
"book": {
"id": "133556360140246",
"url": "https://www.facebook.com/pages/Pride-and-Prejudice/133556360140246",
"type": "books.book",
"title": "Pride and Prejudice"
}
},
"type": "books.reads",
"no_feed_story": false,
"likes": {
"count": 0,
"can_like": true,
"user_likes": false
},
"comments": {
"count": 0,
"can_comment": true,
"comment_order": "chronological"
}
},
{
"id": "270170328",
"from": {
"name": "h",
"id": "100004346894022"
},
"start_time": "2014-01-22T09:29:42+0000",
"publish_time": "2014-01-22T09:29:42+0000",
"application": {
"name": "Books",
"id": "174275722710475"
},
"data": {
"book": {
"id": "104081659627680",
"url": "https://www.facebook.com/pages/Gulistan-of-Sadi/104081659627680",
"type": "books.book",
"title": "Gulistan of Sa'di"
}
},
"type": "books.reads",
"no_feed_story": false,
"likes": {
"count": 0,
"can_like": true,
"user_likes": false
},
"comments": {
"count": 0,
"can_comment": true,
"comment_order": "chronological"
}
}
],
I need books titles and their URL. I run the below code but I get Exception in thread "main" java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to java.lang.String
while ((inputLine = in.readLine()) != null)
{
s = s + inputLine + "\r\n";
if (s == null) {
break;
}
t = t + inputLine + "\r\n";
}
in.close();
t = t.substring(0, t.length() - 2);
System.out.println(t);
Object dataObj =JSONValue.parse(t);
System.out.println(dataObj);
JSONObject dataJson = (JSONObject) dataObj;
JSONArray data = (JSONArray) dataJson.get("data");
for (Object o: data)
{
JSONObject indata= (JSONObject) o;
Object indatafirst=(JSONObjec`enter code here`t).get("0");
String inndata=(String) indatafirst.get("data");
System.out.println("inndata"+inndata);
}}
but it is not true
The problem is with the following line:
String inndata=(String) indatafirst.get("data");
The data field in the JSON is not a String, it's a nested JSON object.
"data": {
"book": {
"id": "104081659627680",
"url": "https://www.facebook.com/pages/Gulistan-of-Sadi/104081659627680",
"type": "books.book",
"title": "Gulistan of Sa'di"
}
}
This explains your ClassCastException.
Instead you should do something like:
JSONObject data = (JSONObject) indatafirst.get("data");
JSONObject book = (JSONObject) data.get("book");
String bookTitle = book.get("title");
I searched across many sources but could not find the answer to this one..
Its a know fact that a JSONObject keys are returned in reverse order.
Is there any way to recurse through a JSONObject in the correct order as appearing in JSON
String json;
JSONObject obj = new JSONObject(json)
Iterator<String> keys = json.keys() ---> order is reversed
I understand JSONObject is unordered, perhaps there is a way to order it????
JSON is of type below..and the keys start getting recursed from the bottom most styleHint tag
"sections": {
"1": {
"1": {
"1": {
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"2": {
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
},
"2": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"2": {
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
},
"anchor":"xxx"
},
"3": {
"1": {
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"tag": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"tag": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxxx"
}
},
"styleHint": {
"1": {
"name": "xx",
"title": "xxx",
"id": "xxxx"
}
}
}
}
}
How about that
Get your org.json.JSONObject source and change these
public ListIterator keys() {
ListIterator iter = new ArrayList(this.keySet()).listIterator();
return iter;
}
and
/**
* Construct an empty JSONObject.
*/
public JSONObject() {
this.map = new LinkedHashMap();
}
and
/**
* The map where the JSONObject's properties are kept.
*/
private final LinkedHashMap map;
and
public JSONObject(Map map) {
this.map = new LinkedHashMap();
if (map != null) {
Iterator i = map.entrySet().iterator();
while (i.hasNext()) {
Map.Entry e = (Map.Entry) i.next();
Object value = e.getValue();
if (value != null) {
this.map.put(e.getKey(), wrap(value));
}
}
}
}
I hope I don't burn in hell for that.