3

I made a small MVC4 app wich returns data from an SQL server as an API, the local url is http://10.0.0.116:35577/api/articoli (I have already enabled network access to the local IIS instance, this actually stopped me for a whole day until I figured it out), the format it returns is the following:

[{"id":0,"desc":"Pizza"},{"id":1,"desc":"Pasta"},{"id":2,"desc":"Science"},{"id":3,"desc":"spaghetti"},{"id":4,"desc":"sfas"},{"id":5,"desc":"test"}]

calling http://10.0.0.116:35577/api/articoli/1 returns a single element:

{"id":1,"desc":"Pasta"}

I've been having trouble parsing this from my android app, from what I gather that array is supposed to have a header name or something, which is totally absent here and I can't really figure how to add it in here, or if I really need to have one at all.

From what I can gather the parser class I got from a tutorial is not suited to this kind of data and I can't really figure out how to make it work with such a result.

The parser is the following:

public class JSONParser {

static InputStream is = null;
static JSONObject jObj = null;
static String json = "";

// constructor
public JSONParser() {

}

public JSONObject getJSONFromUrl(String url) {

    // Making HTTP request
    try {

        URL aaa = new URL(url);
        URLConnection uConnection = aaa.openConnection();
        uConnection.connect();


        //is = httpEntity.getContent();
        is = aaa.openStream();

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, /*"UTF-8"*/ "iso-8859-1"), 8);
        StringBuilder sb = new StringBuilder();
        String line = null;
        while ((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }
        is.close();
        json = sb.toString();
    } catch (Exception e) {
        Log.e("Buffer Error", "Error converting result " + e.toString());
    }

    // try parse the string to a JSON object
    try {
        jObj = new JSONObject(json);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

    // return JSON String
    return jObj;

}
}

I had to edit the url retrieval part of the parser because it tried to get the data by using POST, which the server application interpreted as an attempt at inserting data and called the wrong method,

And this is piece of code in which the parser is called, it's supposed to retrieve each element and then place each one as a row in a listview, which then clicked should call an activity that will read a single element:

private void fillDataJSON() {
        JSONParser jParser = new JSONParser();

        JSONObject json = jParser.getJSONFromUrl(URL);
        JSONArray articoli;
        try {
            articoli = json.getJSONArray("Articoli");

            if (articoli == null) {
                throw new NullPointerException();
            }

            for(int i = 0; i< articoli.length(); i++) {
                JSONObject c = articoli.getJSONObject(i);

                String id = c.getString(KEY_ID);
                String desc = c.getString(KEY_DESC);

                HashMap<String, String> map = new HashMap<String, String>();

                map.put(KEY_ID, id);
                map.put(KEY_DESC, desc);

                menuItems.add(map);

                adapter = new SimpleAdapter(ApiTest.this, menuItems,
                        R.layout.activity_api_test_row,
                        new String[] { KEY_DESC },
                        new int[] { R.id.TextView01 });
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

The error I get is the following:

03-13 10:05:33.291: E/JSON Parser(11811): Error parsing data org.json.JSONException: Value [{"id":0,"desc":"Pizza"},{"id":1,"desc":"Pasta"},{"id":2,"desc":"Science"},{"id":3,"desc":"spaghetti"},{"id":4,"desc":"sfas"},{"id":5,"desc":"test"}] of type org.json.JSONArray cannot be converted to JSONObject

Can this be fixed on the android side or do I have to change how my server works?

The server just returns the data through the controller and everything else is left to the framework, example:

 public IEnumerable<Articoli> GetAllArticoli()
    {
        return repository.GetAll();
    }

doesn't do anything other than that

1
  • you know when the data is JSONArray(when calling api/articoli) and when it is JSONObject(when calling api/articoli/1), you need to parse the string accordingly. Commented Mar 13, 2013 at 9:55

2 Answers 2

3

The root element of a JSON document can be either a JSONObject or a JSONArray (or one of the primitives). You're always parsing it as an object:

// try parse the string to a JSON object
try {
    jObj = new JSONObject(json);
} catch (JSONException e) {
    Log.e("JSON Parser", "Error parsing data " + e.toString());
}

You should parse it as a new JSONArray(json) when the document's root element is an array. You can do this safely by using JSONTokener:

// try parse the string to a JSON object
try {
    JSONTokener jt = new JSONTokener(json);
    Object rootElement = jt.nextValue();
    if (rootElement instanceof JSONObject) {
       // You got an object from the response
    } else if (rootElement instanceof JSONArray) {
       // You got a JSON array
    }
    // else... -> it can also be String, Boolean, Integer, Long or Double
} catch (JSONException e) {
    Log.e("JSON Parser", "Error parsing data " + e.toString());
}

If you know what you're requesting then it's easier to just use the correct response type.

Sign up to request clarification or add additional context in comments.

1 Comment

Beat me to it good sir! This is exactly what I was going to write. He'll also need to change the return type of the method, and the type of the class level variable which he's storing the JSON in
1

You can simply change your code inside fillDataJSON().Just change the type from JSONObject to JSONArray

JSONArray json = jParser.getJSONFromUrl(URL);
        JSONArray articoli;
        try {
            articoli = json;

and in your JSONParser change to:

// try parse the string to a JSON object
    try {
        jObj = new JSONArray(json);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

and change the type of jObj to JSONArray

static JSONArray jObj = null;

and the return type of the class from JSONObject to JSONArray

public JSONObject getJSONFromUrl(String url) {

4 Comments

set breakpoints and debug the code to find the issue.I believe this piece of code would insha Allah solve your issue.Your problem may be somewhere else now?
Don't worry, my problem now is another one past this issue, thanks for the answer though because along with the previous answer, this is basically what I did
glad to help .. You can make a question out of the other issue and point me to that one again.Lets see if i can solve that faster than some one else? :smile:
don't worry, it's just that every element shows in the listview as NULL, I must have messed up somewhere but doesn't matter because I can solve it easily enough

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.