简体   繁体   中英

I'm using the answer from another SO post and I'm getting an exception JSONArray cannot be converted to JSONObject. How can I get this resolved?

Here is the answer I'm using How to implement Login with HttpURLConnection and PHP server in Android

Here is my JSONParser.java:

package com.example.android.simplejson;

import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;

public class JSONParser {

    String charset = "UTF-8";
    HttpURLConnection conn; // Connection
    DataOutputStream wr;    // Write
    StringBuilder result;
    URL urlObj;
    JSONObject jObj = null;
    StringBuilder sbParams;
    String paramsString;

    public JSONObject makeHttpRequest(String url, String method,
                                      HashMap<String, String> params) {

        sbParams = new StringBuilder();
        int i = 0;
        for (String key : params.keySet()) {
            try {
                if (i != 0){
                    sbParams.append("&");
                }
                sbParams.append(key).append("=")
                        .append(URLEncoder.encode(params.get(key), charset));

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            i++;
        }

        if (method.equals("POST")) {
            // request method is POST
            try {
                urlObj = new URL("my_url");

                conn = (HttpURLConnection) urlObj.openConnection();

                conn.setDoOutput(true);

                conn.setRequestMethod("POST");

                conn.setRequestProperty("Accept-Charset", charset);

                conn.setReadTimeout(10000);
                conn.setConnectTimeout(15000);

                conn.connect();

                paramsString = sbParams.toString();

                wr = new DataOutputStream(conn.getOutputStream());
                wr.writeBytes(paramsString);
                wr.flush();
                wr.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else if(method.equals("GET")){
            // request method is GET

            try {
                urlObj = new URL("my_url");

                conn = (HttpURLConnection) urlObj.openConnection();

                conn.setDoOutput(false);

                conn.setRequestMethod("GET");

                conn.setRequestProperty("Accept-Charset", charset);

                conn.setConnectTimeout(15000);

                conn.connect();

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

        }

        try {
            //Receive the response from the server
            InputStream in = new BufferedInputStream(conn.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            result = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
                Log.d("Response: ", "> " + line); //here you'll get the whole response
            }

            Log.d("JSON Parser", "result: " + result.toString());

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

        conn.disconnect();

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

        // return JSON Object
        return jObj;
    }
}

Here is a snippet of my MainActivity.java:

class checkLogin extends AsyncTask<String, String, JSONObject> {
        JSONParser jsonParser = new JSONParser();

        private ProgressDialog pd;

        private static final String LOGIN_URL = "my_url";

        private static final String TAG_SUCCESS = "success";
        private static final String TAG_MESSAGE = "message";

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pd = new ProgressDialog(MainActivity.this);
            pd.setMessage("Attempting login...");
            pd.setIndeterminate(false);
            pd.setCancelable(true);
            pd.show();
        }

        protected JSONObject doInBackground(String... params) {

            try {

                HashMap<String, String> credentials = new HashMap<>();
                credentials.put("username", params[0]);
                credentials.put("password", params[1]);

                Log.d("request", "starting");

                JSONObject json = jsonParser.makeHttpRequest(
                        LOGIN_URL, "POST", credentials);

                if (json != null) {
                    Log.d("JSON result", json.toString());

                    return json;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(JSONObject json) {

            int success = 0;
            String message = "";

            if (pd != null && pd.isShowing()) {
                pd.dismiss();
            }

            if (json != null) {
                Toast.makeText(MainActivity.this, json.toString(),
                        Toast.LENGTH_LONG).show();

                try {
                    success = json.getInt(TAG_SUCCESS);
                    message = json.getString(TAG_MESSAGE);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            if (success == 1) {
                Log.d("Success!", message);
            } else {
                Log.d("Failure", message);
            }
        }
    }
}

It gets a JSONArray from the server [{"AuthStatus":true,"AuthMessage":"This is my sample message","username":"username=&password="}]

My problem is the JSONArray can't be converted to JSONObject. So what can I change in my code to return the JSONArray as jObj? My ultimate goal is to set the text in my main activity as [{"AuthStatus":true,"AuthMessage":"This is my sample message","username":"username=&password="}].

Thanks!

You can't parse a JSON array as a JSON object. First you have to parse the payload as an array and then get the object from it.

public JSONObject makeHttpRequest(String url, String method,
    HashMap<String, String> params) {

    // ...

    try {
        JSONArray jArr = new JSONArray(result.toString());
        jObj = jArr.getJSONObject(0);
    } catch (JSONException e) {
        Log.e("JSON Parser", "Error parsing data " + e.toString());
    }

    // return JSON Object
    return jObj;
}

Refer the below exampe :

String str = {"xyz":[{"name":"apple","email_id":"apple@apple.com"}]};
JSONObject json = JSONObject.fromObject(str);

So essentially your response is in format of a JSONArray [{"AuthStatus":true,"AuthMessage":"This is my sample message","username":"username=&password="}]'

where it should have been something like

{"response": [{"AuthStatus":true,"AuthMessage":"This is my sample message","username":"username=&password="}]}

or simply

{"AuthStatus":true,"AuthMessage":"This is my sample message","username":"username=&password="}

depending on your preference. If you are always going to return a single JSONObject (probably as this is a login service response) there is no need to use the square braces which makes it a JSONArray.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM