从mySql db调用时,JSON返回NullPointerException

I've tried connecting my android app to online mySQL databse using this tutorial: http://www.androidhive.info/2012/05/how-to-connect-android-with-php-mysql/ but I am getting an error that says

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.json.JSONObject.toString()' on a null object reference

in the doInBackground portion where i try to call json.ToString():

package com.example.androidhive;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class NewProductActivity extends Activity {

    // Progress Dialog
    private ProgressDialog pDialog;

    JSONParser jsonParser = new JSONParser();
    EditText inputName;
    EditText inputPrice;
    EditText inputDesc;

    // url to create new product
    private static String url_create_product = "http://lewspage.hostei.com/scripts/create_product.php";

    // JSON Node names
    private static final String TAG_SUCCESS = "success";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_product);

        // Edit Text
        inputName = (EditText) findViewById(R.id.inputName);
        inputPrice = (EditText) findViewById(R.id.inputPrice);
        inputDesc = (EditText) findViewById(R.id.inputDesc);

        // Create button
        Button btnCreateProduct = (Button)      findViewById(R.id.btnCreateProduct);

        // button click event
        btnCreateProduct.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                // creating new product in background thread
                new CreateNewProduct().execute();
            }
        });
    }

    /**
     * Background Async Task to Create new product
     * */
    class CreateNewProduct extends AsyncTask<String, String, String> {

        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(NewProductActivity.this);
            pDialog.setMessage("Creating Product..");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }

        /**
         * Creating product
         * */
        protected String doInBackground(String... args) {
            String name = inputName.getText().toString();
            String price = inputPrice.getText().toString();
            String description = inputDesc.getText().toString();

            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("name", name));
            params.add(new BasicNameValuePair("price", price));
            params.add(new BasicNameValuePair("description", description));

            // getting JSON Object
            // Note that create product url accepts POST method
            JSONObject json = jsonParser.makeHttpRequest(url_create_product,
                    "POST", params);

            // check log cat fro response
            Log.d("Create Response", json.toString()); //Crashes here

            // check for success tag
            try {
                int success = json.getInt(TAG_SUCCESS);

                if (success == 1) {
                    // successfully created product
                    Intent i = new Intent(getApplicationContext(), AllProductsActivity.class);
                    startActivity(i);

                    // closing this screen
                    finish();
                } else {
                    // failed to create product
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
            // dismiss the dialog once done
            pDialog.dismiss();
        }

    }
}

The PHP script at "http://lewspage.hostei.com/scripts/create_product.php" is as follows:

<?php

/*
 * Following code will create a new product row
 * All product details are read from HTTP Post Request
 */
require_once('db_connect.php');

    $host='mysql10.000webhost.com';
    $user='myusername';
    $pass='mypassword';


    if ( !mysql_connect($host,$user,$pass) ||
    !mysql_select_db('a7390942_test') )
        echo 'ERROR';

    else
               echo 'OKKKK';

// array for JSON response
$response = array();

// check for required fields
if (isset($_POST['name']) && isset($_POST['price']) && isset($_POST['description'])) {

    $name = $_POST['name'];
    $price = $_POST['price'];
    $description = $_POST['description'];

    // include db connect class
    require_once __DIR__ . '/db_connect.php';

    // connecting to db
    $db = new DB_CONNECT();

    // mysql inserting a new row
    $result = mysql_query("INSERT INTO products(name, price, description) VALUES('$name', '$price', '$description')");

    // check if row inserted or not
    if ($result) {
        // successfully inserted into database
        $response["success"] = 1;
        $response["message"] = "Product successfully created.";

        // echoing JSON response
        echo json_encode($response);
    } else {
        // failed to insert row
        $response["success"] = 0;
        $response["message"] = "Oops! An error occurred.";

        // echoing JSON response
        echo json_encode($response);
    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>  

Basically , I used 000wehost to host the mysql database as well as the php scripts. I tried to run the create_product script on its own and it has no problem connecting to the database.I have already ensured that my databse contains the fields name,price,description. However, I don't know why it doesn't seem to fill the JSON object properly .

Thanks

Change the line where you have json.toString() to below. This is because makeHttpRequest can return null:

Log.d("Create Response", ((json == null) ? "" :json.toString());

Also make sure the JsonParser object you initialized is the one you are using.

The main problem that you are having is that the URL you provided does not return proper JSON. This is probably due to an error in your PHP script or the free webhost that you are using is injecting content in your response.

In any case you should never trust the result of an http call and always test that you do get back the result you expect before using the data.

You can use a tool like postman to test calls to http services and examine the actual result. In your case when I test your URL what returns is not JSON.

When I accessed the url you provided, it isn't a valid string because your 'db_connect.php' script did not open properly.

?php /* * All database connection variables */ define('DB_USER', "replace"); // db user define('DB_PASSWORD', "replace"); // db password (mention your db password here) define('DB_DATABASE', "replace"); // database name define('DB_SERVER', "replace"); // db server ?>OKKKK{"success":0,"message":"Required field(s) is missing"}

This is what the response is from the url. I'm assuming the code below is your db_connect.php script

?php /* * All database connection variables */ define('DB_USER', "replace"); // db user define('DB_PASSWORD', "replace"); // db password (mention your db password here) define('DB_DATABASE', "replace"); // database name define('DB_SERVER', "replace");?>

You are lacking a < in your php opening tag. Also, considering removing some of the echo function that may hinder your json.

I'll break it down for you. You might noticed OKKKK because the database is successfully connected based on your script:

if ( !mysql_connect($host,$user,$pass) ||
    !mysql_select_db('a7390942_test') )
        echo 'ERROR';

    else
               echo 'OKKKK';

You need to remove those echo because it will make your webpage response not conforming to JSON standard. Next, your db_connect script probably didn't open correctly, thus exposing all your database definition.

Note: It is recommended to use prepare statement for mysqli due to the fact that you are inserting the table with user input. Without prepare statement, your sql will be injectable.

Suggestion to you is that since you're using free webhost provider, you can't be sure whether they append any text to your response. You could possibly enclosed your json text within a html element and give it a class. In your android, get all the html response, convert to string and then substring text after your class and before it closes.

Example:

<div class="jsonTxt">{"success":"1"}</div>

So I would read the string after and then read the index of the from the substring-ed text and then remove anything after it.