8

I'm trying to parse a JSON object, part of which looks like this:

{
"offer":{
    "category":"Salon",
    "description":"Use this offer now to enjoy this great Salon at a 20% discount. ",
    "discount":"20",
    "expiration":"2011-04-08T02:30:00Z",
    "published":"2011-04-07T12:00:33Z",
    "rescinded_at":null,
    "title":"20% off at Jun Hair Salon",
    "valid_from":"2011-04-07T12:00:31Z",
    "valid_to":"2011-04-08T02:00:00Z",
    "id":"JUN_HAIR_1302177631",
    "business":{
        "name":"Jun Hair Salon",
        "phone":"2126192989",
        "address":{
            "address_1":"12 Mott St",
            "address_2":null,
            "city":"New York",
            "cross_streets":"Chatham Sq & Worth St",
            "state":"NY",
            "zip":"10013"
        }
    },

And so on....

So far, I'm able to parse very simply, by doing this kinda thing:

JSONObject jObject = new JSONObject(content);
JSONObject offerObject = jObject.getJSONObject("offer");
String attributeId = offerObject.getString("category");
System.out.println(attributeId);

String attributeValue = offerObject.getString("description");
System.out.println(attributeValue);

String titleValue = offerObject.getString("title");
System.out.println(titleValue);`

But when I try it for 'name:' it won't work.

I've tried:

JSONObject businessObject = jObject.getJSONObject("business");
String nameValue = businesObject.getString("name");
System.out.println(nameValue);

When I try that, I get "JSONObject [business] not found."

And when I try:

String nameValue = offerObject.getString("name");
System.out.println(nameValue);`

I get, as expected, "JSONObject [name] not found".

What am I doing wrong here? I'm missing something basic....

Sam
  • 86,580
  • 20
  • 181
  • 179
LuxuryMode
  • 33,401
  • 34
  • 117
  • 188
  • hi i refred the following page and got the solution http://stackoverflow.com/questions/5986123/parsing-nested-json-object-in-android –  Jan 10 '12 at 08:28

3 Answers3

35

Ok, I'm an idiot. This works.

JSONObject businessObject = offerObject.getJSONObject("business");
String nameValue = businessObject.getString("name");
System.out.println(nameValue);

If I would only think for two seconds before posting... Jees!

LuxuryMode
  • 33,401
  • 34
  • 117
  • 188
19

Here a single-line solution

String myString = myJsonObject.getJSONObject("offer").getJSONObject("business").getString("name");
Alecs
  • 2,900
  • 1
  • 22
  • 25
3

Note that serializing/deserializing JSON to/from Java objects doesn't have to be done "manually". Libraries like GSON and Jackson make it very easy.

import java.text.DateFormat;
import java.util.Date;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Foo { static String jsonInput = "{" + "\"offer\":{" + "\"category\":\"Salon\"," + "\"description\":\"Use this offer now to enjoy this great Salon at a 20% discount. \"," + "\"discount\":\"20\"," + "\"expiration\":\"2011-04-08T02:30:00Z\"," + "\"published\":\"2011-04-07T12:00:33Z\"," + "\"rescinded_at\":null," + "\"title\":\"20% off at Jun Hair Salon\"," + "\"valid_from\":\"2011-04-07T12:00:31Z\"," + "\"valid_to\":\"2011-04-08T02:00:00Z\"," + "\"id\":\"JUN_HAIR_1302177631\"," + "\"business\":{" + "\"name\":\"Jun Hair Salon\"," + "\"phone\":\"2126192989\"," + "\"address\":{" + "\"address_1\":\"12 Mott St\"," + "\"address_2\":null," + "\"city\":\"New York\"," + "\"cross_streets\":\"Chatham Sq & Worth St\"," + "\"state\":\"NY\"," + "\"zip\":\"10013\"" + "}" + "}" + "}" + "}";

public static void main(String[] args) throws Exception { GsonBuilder gsonBuilder = new GsonBuilder(); // gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); gsonBuilder.setDateFormat(DateFormat.LONG); Gson gson = gsonBuilder.create(); OfferContainer offerContainer = gson.fromJson(jsonInput, OfferContainer.class); System.out.println(offerContainer); } }

class OfferContainer { private Offer offer;

@Override public String toString() { return offer.toString(); } }

class Offer { private Category category; private String description; private String discount; private Date expiration; private Date published; private String rescinded_at; private String title; private Date valid_from; private Date valid_to; private String id; private Business business;

@Override public String toString() { return String.format( "[Offer: category=%1$s, description=%2$s, discount=%3$s, expiration=%4$s, published=%5$s, rescinded_at=%6$s, title=%7$s, valid_from=%8$s, valid_to=%9$s, id=%10$s, business=%11$s]", category, description, discount, expiration, published, rescinded_at, title, valid_from, valid_to, id, business); } }

enum Category { Salon }

class Business { private String name; private String phone; private Address address;

@Override public String toString() { return String.format( "[Business: name=%1$s, phone=%2$s, address=%3$s]", name, phone, address); } }

class Address { private String address_1; private String address_2; private String city; private String cross_streets; private String state; private String zip;

@Override public String toString() { return String.format( "[Address: address_1=%1$s, address_2=%2$s, city=%3$s, cross_streets=%4$s, state=%5$s, zip=%6$s]", address_1, address_2, city, cross_streets, state, zip); } }

Note that a FieldNamingPolicy can be used to easily map attribute names from the JSON to the Java code. The LOWER_CASE_WITH_UNDERSCORES policy unfortunately does not work with JSON attribute names like "address_1".

If the performance of JSON handling is a concern, then take a look at Jackson Vs. Gson and http://www.cowtowncoder.com/blog/archives/2011/01/entry_437.html

Community
  • 1
  • 1
Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
  • Wow, this is awesome stuff. Thanks so much. Was gonna accept my own answer, but now I'm not so sure.... ;) – LuxuryMode May 13 '11 at 23:13
  • 1
    I forgot to mention a couple of things. 1. GSON is built into Android 3.0+. Just use AndroidJsonFactory. 2. The HTC folks introduced a bug with using GSON on some HTC devices. The workaround is to just use jarjar to move the GSON code to another package. See http://code.google.com/p/google-gson/issues/detail?id=255 – Programmer Bruce May 14 '11 at 04:21
  • sort of a separate issue, but what's the easiest way to get a string of the json from an HttpURLConnection? – LuxuryMode Jun 05 '11 at 05:51
  • @Programmer Bruce - how would I put a json array into my String.format method? – LuxuryMode Jun 05 '11 at 14:27
  • I don't know what that means. Are you trying to serialize Java objects to generate a JSON string? – Programmer Bruce Jun 05 '11 at 21:36
  • Sorry, I wasn't very clear. Say, I get some JSON data that looks like this: http://pastebin.com/cmC7xpPS How can I deserialize the whole thing in the manner you showed above? – LuxuryMode Jun 05 '11 at 23:56
  • Is this related to the other active question you've got going? It's confusing how you ask different and related and overlapping questions in one post and in comments and in different posts. – Programmer Bruce Jun 05 '11 at 23:58
  • Sorry for the confusion and for being a little all over the place. What I'm looking to do is to just take an entire JSON file (like this one: http://pastebin.com/cmC7xpPS), parse it, and convert it into a bunch of regular 'ol java objects. So at the end of the day, I want to be able to have a bunch of Offer objects, each with getters so I can easily access the values of the JSON object. – LuxuryMode Jun 06 '11 at 00:11
  • Less than an hour ago I posted a solution for this in your other question. Why are you asking about it, again? – Programmer Bruce Jun 06 '11 at 00:13
  • Bruce, I'm terribly sorry and, at the risk of wearing your patience thin (as if it isn't already): I think what I'm confused about is how to serialize the json data into as many Offer objects as are contained in whatever json I retrieved by my remote API call. In your other post, you "manually" created new offer objects, put them into an array and then serialized them. But what if I don't know how many offers are returned in the json? I just want to be able to make an http request, get the json string, parse the whole thing and add each offer object to an ArrayList of offer (java) objects. – LuxuryMode Jun 06 '11 at 00:21
  • Look at the solution I posted in the other thread, again. It also includes an example of deserializing from JSON into an array of Offer objects. I don't see how this differs from what you're now asking about, other than the Offer object you're now referencing has more attributes. – Programmer Bruce Jun 06 '11 at 00:27