Failure to parse this json field - java

I can get other fields correctly, but can parse the "title" or "title_full" values. I always receives an empty string. I am using the org.json library. This is the json. What's the trick?
try {
title = jsonDoc.getString("title_full");
} catch (JSONException e) {
log.info("no full title: " + docString);
}
{
"organizations": [],
"uuid": "d0adc516c9012113774557365f9847da99b228e7",
"thread": {
"site_full": "www.fark.com",
"main_image": "http://img.fark.net/images/cache/orig/5/51/fark_514Jh7VFpynQw4MyN2xcK1jwCxk.png?t=RQrnhq8EGZiUuElMitgLOQ&f=1488776400",
"site_section": "http://www.fark.com/discussion/",
"section_title": "FARK.com: Discussion links",
"url": "http://www.fark.com/comments/9500577/I-want-to-support-work-that-NY-Times-Washington-Post-are-doing-I-can-only-afford-one-subscription-Who-do-you-recommend-I-throw-my-support-to?cpp=1",
"country": "US",
"domain_rank": 3382,
"title": "(9500577) I want to support the work that the NY Times and Washington Post are doing. I can only afford one subscription. Who do you recommend I throw my support to?",
"performance_score": 0,
"site": "fark.com",
"participants_count": 31,
"title_full": "FARK.com: (9500577) I want to support the work that the NY Times and Washington Post are doing. I can only afford one subscription. Who do you recommend I throw my support to?",
"spam_score": 0.0,
"site_type": "discussions",
"published": "2017-03-03T12:00:00.000+02:00",
"replies_count": 2,
"uuid": "67213179a24931106e75cd588386bd30fb3bbdc8"
},
"author": "EbolaNYC",
"url": "http://www.fark.com/comments/9500577/I-want-to-support-work-that-NY-Times-Washington-Post-are-doing-I-can-only-afford-one-subscription-Who-do-you-recommend-I-throw-my-support-to?cpp=1#c107765048",
"ord_in_thread": 1,
"title": "",
"locations": [],
"entities": {
"persons": [],
"locations": [],
"organizations": []
},
"highlightText": "",
"language": "english",
"persons": [],
"text": "dionysusaur : Either the NY Post or the WA Times.\nOnly asshats read the NY Post.",
"external_links": [],
"published": "2017-03-03T15:58:00.000+02:00",
"crawled": "2017-03-03T17:05:26.049+02:00",
"highlightTitle": "",
"social": {
"gplus": {"shares": 0},
"pinterest": {"shares": 0},
"vk": {"shares": 0},
"linkedin": {"shares": 0},
"facebook": {"likes": 0, "shares": 0, "comments": 0},
"stumbledupon": {"shares": 0}
}
}

Your JSON seems like follows:
{
{
"main": {
"key": "value",
},
},
}
So, First fetch the main json and then the key.
Code should be like as follows:
String something = jsonDoc.get("main").get("key").toString();
There are two title values in your JSON, Do check which title you need before fetching.

After I formatted the json code, the problem becomes obvious:
title_full is only available inside the thread node, and a non-empty title is also only inside the thread node. So you'll first have to access the thread node and then access title and title_full inside that node.
Using the org.json library, you can access the fields like this:
String fullTitle = jsonDoc.getJSONObject("thread").getString("title_full");

If you take a look at the json you will see that the "title" and "title_full" fields are in the thread field.
So try reading that field and then parsing the filed into a new jsonObject and you should be able to get them.

Related

talend: Merge multiple (complex) flat files into single JSON file

I'm testing talend for its potential use in a project - basic tasks are completed easily, however I'm struggling with the following sitution:
We have multiple flat files, all of which combine to describe various items. For my testing, I would simply like to merge two of these files (for now) into a JSON format. The catch here is that one of the files contains 1 or more rows per item;
For example:
File 1: id, category
1, A
2, A
3, B
File 2: id, language, colour
1, en_GB, Red
1, de_DE, Rot
2, en_GB, Blue
3, en_GB, Green
3, de_DE, Grün
3, es_ES, Verde
The result should look something like this:
{
items[{
"id": 1,
"category": "A",
"colours": [{
"language": "en_GB",
"colour": "Red"
}, {
"language": "de_DE",
"colour": "Rot"
}],
},
...
}
What I have tried so far is:
tMap to merge the files/rows together, then tAggregate to group by the id's. This does not quite work, as it results in the language and colour attributes being formatted individually as comma separated lists:
ie.
"language": "en_GB, de_DE",
"colour": "Red, Rot"
This is not what we require.
Is it possible to achieve what we need in talend? If so, how?
Here's a solution I put together, using java json library, since json components do not handle such complex structure.
tAggregateRow settings:
First, load the json-java.jar using a tLibraryLoad. Then join data using a tMap (on the id column, returning all matches), then aggregate it using the id, and output a list of objects for language and colour. Then in tJavaFlex, loop over the rows to construct the final json (here's the java code).
This gives the below formatted output, based on your example :
{
items: [{
"id": 1,
"category": "A",
"colours": [{
"colour": "Red",
"language": "en_GB"
}, {
"colour": "Rot",
"language": "de_DE"
}
]
}, {
"id": 2,
"category": "A",
"colours": [{
"colour": "Blue",
"language": "en_GB"
}
]
}, {
"id": 3,
"category": "B",
"colours": [{
"colour": "Green",
"language": "en_GB"
}, {
"colour": "Grün",
"language": "de_DE"
}, {
"colour": "Verde",
"language": "es_ES"
}
]
}
]
}

How to get specific bits of json response effectively?

Im requesting data from instagram api when I search for any tag. In return I get a massive chunk of json data corresponding to like 20 pictures. The response below is the chunk I used to generate my pojos online
{
"pagination": {
"next_max_tag_id": "1193052000552992097",
"deprecation_warning": "next_max_id and min_id are deprecated for this endpoint; use min_tag_id and max_tag_id instead",
"next_max_id": "1193052000552992097",
"next_min_id": "1193052554319844057",
"min_tag_id": "1193052554319844057",
"next_url": "https://api.instagram.com/v1/tags/cats/media/recent?access_token=631477962.1fb234f.f7c5cda97c7f4df983b1c764f066ed37&max_tag_id=1193052000552992097"
},
"meta": {
"code": 200
},
"data": [
{
"attribution": null,
"tags": [
"cats",
"caseworker",
"homestuck"
],
"type": "image",
"location": null,
"comments": {
"count": 0,
"data": []
},
"filter": "Normal",
"created_time": "1456442969",
"link": "https://www.instagram.com/p/BCOkvoim1LZ/",
"likes": {
"count": 0,
"data": []
},
"images": {
"low_resolution": {
"url": "https://scontent.cdninstagram.com/t51.2885-15/s320x320/e35/12729405_224148847934280_1450226662_n.jpg?ig_cache_key=MTE5MzA1MjU1NDMxOTg0NDA1Nw%3D%3D.2",
"width": 320,
"height": 320
},
"thumbnail": {
"url": "https://scontent.cdninstagram.com/t51.2885-15/s150x150/e35/12729405_224148847934280_1450226662_n.jpg?ig_cache_key=MTE5MzA1MjU1NDMxOTg0NDA1Nw%3D%3D.2",
"width": 150,
"height": 150
},
"standard_resolution": {
"url": "https://scontent.cdninstagram.com/t51.2885-15/s640x640/sh0.08/e35/12729405_224148847934280_1450226662_n.jpg?ig_cache_key=MTE5MzA1MjU1NDMxOTg0NDA1Nw%3D%3D.2",
"width": 640,
"height": 640
}
},
"users_in_photo": [],
"caption": {
"created_time": "1456442969",
"text": "Bitch! I'm fabulous! That's my case worker..she is obsessed with cats\n\n#cats #caseworker #homestuck",
"from": {
"username": "strider_inc",
"profile_picture": "https://scontent.cdninstagram.com/t51.2885-19/s150x150/12558836_953196128050469_1739102_a.jpg",
"id": "2322171747",
"full_name": "WE All 4EVER KAWAII TRASH GODS"
},
"id": "1193052563471815092"
},
"user_has_liked": false,
"id": "1193052554319844057_2322171747",
"user": {
"username": "strider_inc",
"profile_picture": "https://scontent.cdninstagram.com/t51.2885-19/s150x150/12558836_953196128050469_1739102_a.jpg",
"id": "2322171747",
"full_name": "WE All 4EVER KAWAII TRASH GODS"
}
}
So when I do that I get like 10-12 different pojo classes into which I should map this data. Now firstly...Im just trying that out and Im 100% Ill have some problem mapping them I mean gson will do it for me but i dont know if there are any more that I would need etc.
but most importantly my app only needs the low standard url pictures all the other information is useless for me.
Ofcourse, I know one way to do it which is to convert the whole thing into a string and parse the whole string through multiple times looking for key words etc and making images etc. I dont want to do that because its ugly. It works but I want a concise way of doing that at the same time without mapping completely.
Using Gson's JsonParser class, you can parse your JSON into a tree of JsonElements, and then extract just the data that you need.
For example, in order to print out all the low resolution URLs, you could use the following code:
String json = "...";
JsonParser parser = new JsonParser();
JsonObject object = parser.parse(json).getAsJsonObject();
JsonArray data = object.getAsJsonArray("data");
for (JsonElement element : data) {
JsonObject images = element.getAsJsonObject().getAsJsonObject("images");
JsonObject lowResolution = images.getAsJsonObject("low_resolution");
String url = lowResolution.getAsJsonPrimitive("url").getAsString();
System.out.println(url);
}
Using your example JSON, this would print:
https://scontent.cdninstagram.com/t51.2885-15/s320x320/e35/12729405_224148847934280_1450226662_n.jpg?ig_cache_key=MTE5MzA1MjU1NDMxOTg0NDA1Nw%3D%3D.2

parsing json in android studio

I am developing first time in android and i have never used json data before. I will develop an application of event calendar of my university. We developed web version application in Django and we implement tastypie (restapi) so i need to use this json data for android mobile version. My json data is like this :
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 5
},
"objects": [{
"Location": "Z011",
"Notes": "asdf",
"Title": "Literature Talking",
"id": 3,
"resource_uri": "/api/v1/Events/3/"
}, {
"Location": "Batı Kampüsü, Sinema Salonua",
"Notes": "sd",
"Title": "TARİHÇE KONFERANSLARI SERİSİ 25",
"id": 4,
"resource_uri": "/api/v1/Events/4/"
}, {
"Location": "in Campus",
"Notes": "afafdf",
"Title": "Self-Assessment Project",
"id": 5,
"resource_uri": "/api/v1/Events/5/"
}, {
"Location": "Kütüphane",
"Notes": "fs",
"Title": "51.Kütüphane Haftası",
"id": 6,
"resource_uri": "/api/v1/Events/6/"
}]
}
how can I parse this Json data in android studio?
Using below code you will be able to get Title and Location
JSONObject obj=new JSONObject(response);//This is response from webservice
String totalCount = obj.getJSONObject("meta").getString("total_count"); //for getting total_count
JSONArray json_array = obj.getJSONArray("objects");
for(int j=0;j<json_array.length();j++) {
String title = json_array.getJSONObject(j).getString("Title");
String location= json_array.getJSONObject(j).getString("Location");
}
Use this website to help you view the Json structure better
http://www.jsontree.com/
What you have is a Json Object since it starts and ends with curly braces.
For example if I had a Json as {"Id":"1"}
The Key is "Id" and the value is "1"
A Json object can have a Json inside the value as well(Which is your case)
And example is {"Id":{"Place1":"1", "Place2":"2"}}
So the Key is "Id" and it has the value "Place1":"1", "Place2":"2"
So the value is also a Json.
It can get a little messy with Jsons in Jsons.
Here is a good tutorial on parsing Json
http://www.tutorialspoint.com/android/android_json_parser.htm

Convert json response to java object

I have json response and I generated java code from this json by tools .But this json object have key like #size ,#order etc ... ,So in my java code some invalid identifier has been generated. When I removed this # symbol with java code I am able to catch the response of json value in my java object expect these value.
I am sure some json annotation is available to do this , means if the json key is not matching with java Object then we can map through this json annotation.
I tried with some Json annotation but is not worked for me and I confused which annotation should I used with getter methods .
here my json code below :-
{
"HotelListResponse": {
"cachedSupplierResponse": {
"#cachedTime": "0",
"#candidatePreptime": "111",
"#matchedCurrency": "true",
"#matchedLocale": "true",
"#otherOverheadTime": "4",
"#supplierRequestNum": "211",
"#supplierResponseNum": "20",
"#supplierResponseTime": "405",
"#tpidUsed": "5001"
},
"cacheKey": "302c317:13443ffb599:-7712",
"cacheLocation": "10.186.168.61:7302",
"customerSessionId": "0ABAA83D-2C31-7913-4432-FFB599907714",
"HotelList": {
"#activePropertyCount": "237",
"#size": "1",
"HotelSummary": {
"#ubsScore": "1867",
"#order": "0",
"hotelId": 127092,
"name": "The Edgewater - A Noble House Hotel",
"address1": "Pier 67, 2411 Alaskan Way",
"city": "Seattle",
"stateProvinceCode": "WA",
"postalCode": 98121,
"countryCode": "US",
"airportCode": "SEA",
"supplierType": "E",
"propertyCategory": 1,
"hotelRating": 4,
"confidenceRating": 85,
"amenityMask": 6259019,
"tripAdvisorRating": 4,
"tripAdvisorReviewCount": 590,
"tripAdvisorRatingUrl": "http://www.tripadvisor.com/img/cdsi/img2/ratings/traveler/4.0-12345-4.gif",
"locationDescription": "Near Washington State Convention & Trade Center",
"shortDescription": "<p><b>Location. </b> <br />The Edgewater - A Noble House Hotel is a business-friendly hotel located in central Seattle, close to Odyssey - The Maritime Discovery Center, Washington State Convention &",
"highRate": 249,
"lowRate": 186.75,
"rateCurrencyCode": "USD",
"latitude": 47.61252,
"longitude": -122.35013,
"proximityDistance": 11.898841,
"proximityUnit": "MI",
"hotelInDestination": true,
"thumbNailUrl": "/hotels/1000000/20000/11200/11133/11133_73_t.jpg",
"deepLink": "http://travel.ian.com/index.jsp?pageName=hotAvail&cid=55505&hotelID=127092&mode=2&numberOfRooms=2&room-0-adult-total=1&room-0-child-total=1&room-0-child-0-age=3&room-1-adult-total=1&room-1-child-total=1&room-1-child-0-age=5&arrivalMonth=8&arrivalDay=4&departureMonth=8&departureDay=5&showInfo=true&locale=en_US&currencyCode=USD",
"RoomRateDetailsList": {
"RoomRateDetails": {
"roomTypeCode": 1160,
"rateCode": 1221260,
"maxRoomOccupancy": 2,
"quotedRoomOccupancy": 2,
"minGuestAge": 0,
"roomDescription": "City Lodge - Nonrefundable",
"promoId": 200803780,
"promoDescription": "7-Day Advance Purchase Special (Nonrefundable)",
"currentAllotment": 10,
"propertyAvailable": true,
"propertyRestricted": false,
"expediaPropertyId": 11133,
"rateKey": "f3525aff-9f4d-4d92-bc1c-144628fcaa30",
"nonRefundable": true,
"RateInfos": {
"#size": "1",
"RateInfo": {
"#rateChange": "false",
"#promo": "true",
"#priceBreakdown": "true",
"RoomGroup": {
"Room": [
{
"numberOfAdults": 1,
"numberOfChildren": 1,
"childAges": 3
},
{
"numberOfAdults": 1,
"numberOfChildren": 1,
"childAges": 5
}
]
},
"ChargeableRateInfo": {
"#commissionableUsdTotal": "373.5",
"#total": "441.74",
"#surchargeTotal": "68.24",
"#nightlyRateTotal": "373.5",
"#averageBaseRate": "249.0",
"#averageRate": "186.75",
"#maxNightlyRate": "186.75",
"#currencyCode": "USD",
"NightlyRatesPerRoom": {
"#size": "1",
"NightlyRate": {
"#promo": "true",
"#rate": "186.75",
"#baseRate": "249.0"
}
},
"Surcharges": {
"#size": "1",
"Surcharge": {
"#amount": "68.24",
"#type": "TaxAndServiceFee"
}
}
}
}
}
}
}
}
}
}
}
and I generated the java classes from above mention json by this tool: http://jsongen.byingtondesign.com/
So here how to map[ #key (value of key start with #) ] in our java classes. Initially java class have #identifier_name but java compiler not support variable name start with # so I have to remove it.And then I am not able to map json value to this variable.
Any help would be appreciated.
Thanks in Advance

Most memory efficient way to re format a JSON array in Java

Say I have a JSON array similar to the following:
[
{
"title": "This is a title",
"year": 2013,
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
"thumbsdown": 256
}
},
{
"title": "This is a title",
"year": 2013,
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
"thumbsdown": 256
}
}
]
And the required output is a JSON array like this:
[
{
"title": "This is a title",
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
}
},
{
"title": "This is a title",
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
}
}
]
Iv'e been researching and it's suggested that the most efficient way would be to parse it using the Jackson streaming API. This is for use on a PaaS with limited memory, so I wish to keep the memory usage to the bare minimum.
Is the best way to parse the JSON with Jackson Streaming API, and construct a new JSON array at the same time or simply remove the elements somehow?
I did something similiar with XML once. You can have the requestor tell you what fields you want to get back, and have it only emit those. In my case I had no control over the 3rd party axis xml view, but once I had the view, when I asked for things from it if it was already there I could give back just the pieces I was interested in. As a bonus, if you are marshalling or unmarshalling real java objects from the JSON after getting the json or XML you don't need to build the part of the object graph you don't care about.

Categories

Resources