【问题标题】:Error parsing JSON after updating php file. Works before PDO, now JSON parsing error更新 php 文件后解析 JSON 时出错。在 PDO 之前工作,现在 JSON 解析错误
【发布时间】:2014-08-20 12:08:04
【问题描述】:

通过 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);

现在的问题是解析错误。日志猫:

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。我怎样才能让消息看起来说凭据不正确,如果输入了正确的组合,以启动新活动?

【问题讨论】:

  • 1.你应该问自己你得到了什么错误/异常...... 2.然后你应该问自己在哪里以及为什么......我很确定通过这两个步骤,这里根本不会有这个问题...... NullPointerException 这里只是因为你“吃了”jsonParser.makeHttpRequest 中的一个错误并返回 null ......所以真正的问题是 JSONException ......好吧......我们越来越近了......现在你应该转储 http 响应......然后分析(如何从 PHP 代码中获取)响应
  • Hum.. 为了使其正常工作,您对 exaclty 进行了哪些更改?我看不出原始 PHP 代码和编辑后的 ​​PHP 代码有什么区别……

标签: java php android sql json


【解决方案1】:

您应该删除要传递给 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 代码中的问题!

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

【讨论】:

  • 感谢您的提示。我还没有回家,所以我回来后会给你答复。干杯人。
  • @PaulGerardAli 好的!请让我了解最新情况,因为 Osman Mutlu 似乎没有发现与我相同的问题,所以我很好奇 :)
  • 我已经使它与上面的代码一起工作(在最后添加)。看看以下问题,因为我仍然需要帮助。谢谢!
  • 嗯,有几种方法可以向用户显示消息:Toast 或 AlertDialog(这只是我最喜欢的两个)。看看there for Toastthere for AlertDialogs。如果您了解面向对象的基础知识,两者都非常简单易用。我会推荐 Toast 来做这样的事情,它超级好用。
  • 为快速响应干杯。欣赏它(Y)
【解决方案2】:

假设第二个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));
}
}

【讨论】:

  • 感谢您的提示。我还没有回家,所以我回来后会给你答复。干杯人。
  • 我使用了上面添加到问题末尾的代码。看看,因为我仍然需要关于新代码下方问题的帮助。谢谢你的回答,不胜感激!
猜你喜欢
  • 2014-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
  • 1970-01-01
相关资源
最近更新 更多