更新php文件后解析JSON出错.在PDO之前工作,现在JSON解析错误


Error parsing JSON after updating php file. Works before PDO, now JSON parsing error

通过chrome,我可以使用数据库(MySQL)的成员登录,我可以创建一个新用户。当我使用应用程序时,我可以创建一个新用户,但是应用程序崩溃了。

使用简单的php(如下所示),我得到了一个正确的响应,并启动了新的活动。这里的问题是正确和不正确的凭据都可以工作。

<?php
$response = array();
if (isset($_POST['username'], $_POST['password'])) {
    $response["success"] = 1;
    $response["message"] = "User Name and password are set";
} else {
    $response["success"] = 0;
    $response["message"] = "User Name and password not set";
}
echo json_encode($response);

下面是我的login.java文件:

package com.amity.paul.amity;
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.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import library.JSONParser;
public class login extends Activity implements OnClickListener{
    private EditText user, pass;
    private Button mSubmit, mRegister;
    // Progress Dialog
    private ProgressDialog pDialog;
    // JSON parser class
    JSONParser jsonParser = new JSONParser();
    //php login script location:
    //localhost :
    //testing on your device
    //put your local ip instead,  on windows, run CMD > ipconfig
    //or in mac's terminal type ifconfig and look for the ip under en0 or en1
    // private static final String LOGIN_URL = "http://xxx.xxx.x.x:1234/webservice/login.php";
    //testing on Emulator:
    private static final String LOGIN_URL = "http://10.0.2.2/amity/login.php";
    //testing from a real server:
    //private static final String LOGIN_URL = "http://www.yourdomain.com/webservice/login.php";
    //JSON element ids from repsonse of php script:
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_MESSAGE = "message";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        //setup input fields
        user = (EditText)findViewById(R.id.username);
        pass = (EditText)findViewById(R.id.password);
        //setup buttons
        mSubmit = (Button)findViewById(R.id.login);
        mRegister = (Button)findViewById(R.id.register);
        //register listeners
        mSubmit.setOnClickListener(this);
        mRegister.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
            case R.id.login:
                new AttemptLogin().execute();
                break;
            case R.id.register:
                Intent i = new Intent(this, register.class);
                startActivity(i);
                break;
            default:
                break;
        }
    }
    class AttemptLogin extends AsyncTask<String, String, String> {
        /**
         * Before starting background thread Show Progress Dialog
         * */
        boolean failure = false;
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(login.this);
            pDialog.setMessage("Attempting login...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }
        @Override
        protected String doInBackground(String... args) {
            // TODO Auto-generated method stub
            // Check for success tag
            int success;
            String username = user.getText().toString();
            String password = pass.getText().toString();
            try {
                // Building Parameters
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("username", username));
                params.add(new BasicNameValuePair("password", password));
                Log.d("request!", "starting");
                // getting product details by making HTTP request
                JSONObject json = jsonParser.makeHttpRequest(
                        LOGIN_URL, "POST", params);
                // check your log for json response
                Log.d("Login attempt", json.toString());
                // json success tag
                success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    Log.d("Login Successful!", json.toString());
                    //save user data
                    SharedPreferences sp = PreferenceManager
                            .getDefaultSharedPreferences(login.this);
                    SharedPreferences.Editor edit = sp.edit();
                    edit.putString("username",username);
                    edit.commit();
                    Intent i = new Intent(login.this, home.class);
                    finish();
                    startActivity(i);
                    return json.getString(TAG_MESSAGE);
                }else{
                    Log.d("Login Failure!", json.getString(TAG_MESSAGE));
                    return json.getString(TAG_MESSAGE);
                }
            } 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 product deleted
            pDialog.dismiss();
            if (file_url != null){
                Toast.makeText(login.this, file_url, Toast.LENGTH_LONG).show();
            }
        }
    }
}

然后我把php改成更高级的,如下所示:

<?php   
$response = array();
if (isset($_POST['username'], $_POST['password'])) {  
    require("config.inc.php");
    try {
        $query = " 
            SELECT 
                id, 
                username, 
                password
            FROM users 
            WHERE 
                username = :username
            AND password = :password
        ";
        $stmt   = $db->prepare($query);
        $result = $stmt->execute(array(':username' => $_POST['username'],
                                       ':password' => $_POST['password']
                         ));
        if($stmt->rowCount() == 1){
            $response["success"] = true;
            $response["message"] = "user found";        
        }else{
            $response["success"] = false;
            $response["message"] = "user not found";
        }
    }
    catch (PDOException $ex) {
        $response["success"] = false;
        $response["message"] = "Database Error1. Please Try Again!";
    }
} else {          
    $response["success"] = false;         
    $response["message"] = "User Name and password not set"; 
}
echo json_encode($response);

问题是解析错误。Logcat:

08-16 15:39:40.620      841-856/com.amity.paul.amity E/JSON Parser﹕ Error parsing data org.json.JSONException: Value  of type java.lang.String cannot be converted to JSONObject
08-16 15:39:40.630      841-856/com.amity.paul.amity W/dalvikvm﹕ threadid=11: thread exiting with uncaught exception (group=0xb3a21ba8)
08-16 15:39:40.670      841-856/com.amity.paul.amity E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
    Process: com.amity.paul.amity, PID: 841
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:300)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
            at java.util.concurrent.FutureTask.run(FutureTask.java:242)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:841)
     Caused by: java.lang.NullPointerException
            at com.amity.paul.amity.login$AttemptLogin.doInBackground(login.java:117)
            at com.amity.paul.amity.login$AttemptLogin.doInBackground(login.java:97)
            at android.os.AsyncTask$2.call(AsyncTask.java:288)
            at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:841)

请使解决方案"新手友好",因为我是新的android应用程序开发。谢谢!

编辑:

我使用以下php修复了这个问题:

<?php   
$response = array();
if (isset($_POST['username'], $_POST['password'])) {  
    require("config.inc.php");
    try {
        $query = " 
            SELECT 
                id, 
                username, 
                password
            FROM users 
            WHERE 
                username = :username
            AND password = :password
        ";
        $stmt   = $db->prepare($query);
        $result = $stmt->execute(array(':username' => $_POST['username'],
                                       ':password' => $_POST['password']
                         ));
        if($stmt->rowCount() == 1){
            $response["success"] = true;
            $response["message"] = "user found";        
        }else{
            $response["success"] = false;
            $response["message"] = "user not found";
        }
    }
    catch (PDOException $ex) {
        $response["success"] = false;
        $response["message"] = "Database Error1. Please Try Again!";
    }
} else {          
    $response["success"] = false;         
    $response["message"] = "User Name and password not set"; 
}
echo json_encode($response);

最后一个问题,在logcat中,它会告诉我success = true/false。我如何使消息显示不正确的凭据,如果输入了正确的组合,启动新的活动?

你应该删除数组中的':'字符你传递给prepare():

$result = $stmt->execute(array('username' => $_POST['username'],
                               'password' => $_POST['password']

因为否则PDO会返回一个空响应,或者更糟的是,一个"警告"或"错误"php语句,这些语句将在最后生成的JSON之前加起来,从而生成一个解析异常。您的php响应看起来像:

Error in line BLA BLA BLA ...
["success": "false", "message":"blablabla"]

你将无法用你的Java应用程序解析。

所以它实际上不是一个问题在你的Android代码!

请求中的':'表示"在给定数组中检查':'之后的值"。

假设第二个php代码是用于登录的,我之前没有使用isset函数,但您可以使用此代码。这真的很简单。

if (!empty($_POST)) {
//gets user's info based off of a username.
$query = " 
        SELECT
            username, 
            password
        FROM login 
        WHERE 
            username = :username 
    ";
$query_params = array(
    ':username' => $_POST['username']
);
try {
    $stmt   = $db->prepare($query);
    $result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
    // For testing, you could use a die and message. 
    //die("Failed to run query: " . $ex->getMessage());
    //or just use this use this one to product JSON data:
    $response->{"success"} = 0;
    $response->{"message"} = "Database Error";
    die(json_encode($response));
}
//This will be the variable to determine whether or not the user's information is correct.
//we initialize it as false.
$validated_info = false;
//fetching all the rows from the query
$row = $stmt->fetch();
$login_ok = false;
if ($row) {
    //if we encrypted the password, we would unencrypt it here, but in our case we just
    //compare the two passwords
    if ($_POST['password'] === $row['password']) {
        $login_ok = true;
    }
}
// If the user logged in successfully, then we send them to the private members-only page 
// Otherwise, we display a login failed message and show the login form again 
if ($login_ok) {
    $response->{"success"} = 1;
    $response->{"message"} = "Login Succesfull";
    die(json_encode($response));
} else {
    $response->{"success"} = 0;
    $response->{"message"} = "Wrong Password";
    die(json_encode($response));
}
}