erroR语言 org.json.JSONException:java.lang.String 类型的值 <br 无法转换为 JSONObject



我正在制作一个用于生成OTP的应用程序,所以我使用了php和我的sql。WAMP 作为本地主机提供商。我的日志猫文件包含

11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONObject
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at org.json.JSON.typeMismatch(JSON.java:111)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at org.json.JSONObject.<init>(JSONObject.java:160)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at org.json.JSONObject.<init>(JSONObject.java:173)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at com.techrefic.app1611.MainActivity$2.onResponse(MainActivity.java:178)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at com.techrefic.app1611.MainActivity$2.onResponse(MainActivity.java:172)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:67)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at android.os.Looper.loop(Looper.java:148)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
11-18 13:27:23.776 1620-1943/system_process W/InputMethodManagerService: Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@7b87dab attribute=null, token = android.os.BinderProxy@ba60539
11-18 13:27:26.741 1317-1603/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 5574322 , only wrote 5436064
11-18 13:28:00.085 1212-1272/? D/hwcomposer: hw_composer sent 84 syncs in 60s
11-18 13:29:00.061 1212-1272/? D/hwcomposer: hw_composer sent 4 syncs in 60s

XML 文件activity_main.xml包含:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.techrefic.app1611.MainActivity"
    android:fitsSystemWindows="true">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:paddingLeft="24dp"
        android:paddingRight="24dp"
        android:orientation="vertical">
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp">
            <EditText
                android:id="@+id/editTextEmail"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="textEmailAddress"
                android:hint="Email"/>
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/editTextPassword"
                android:inputType="textPassword"
                android:hint="Password"/>
        </android.support.design.widget.TextInputLayout>
        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/editTextPhone"
                android:inputType="textEmailAddress"
                android:hint="Mobile Number"/>
        </android.support.design.widget.TextInputLayout>

        <android.support.v7.widget.AppCompatButton
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/buttonRegister"
            android:background="@color/colorPrimary"
            android:textColor="#fff"
            android:layout_marginTop="24dp"
            android:layout_marginBottom="24dp"
            android:padding="12dp"
            android:text="Register"
            android:textSize="24sp"/>
        <TextView android:id="@+id/linkLogin"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="24dp"
            android:padding="12dp"
            android:gravity="center"
            android:text="Already have an account? Login here"
            android:textSize="16sp"/>
    </LinearLayout>

</ScrollView>

dialog_confirm.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="48dp"
    android:paddingRight="24dp"
    android:paddingBottom="24dp"
    android:paddingLeft="24dp"
    android:layout_marginTop="80dp"
    android:layout_marginBottom="80dp"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:background="@color/colorAccent">
    <TextView
        android:layout_width="wrap_content"
        android:text="Enter OTP"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/editTextOtp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"/>
    <android.support.v7.widget.AppCompatButton
        android:id="@+id/buttonConfirm"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="24dp"
        android:layout_marginTop="24dp"
        android:background="@color/colorPrimary"
        android:padding="12dp"
        android:text="Confirm Otp"
        android:textColor="#fff"
        android:textSize="24sp"/>
</LinearLayout>

我的 Java 文件是 1。主要活动.java

   public class MainActivity extends AppCompatActivity implements View.OnClickListener {
      //    Creating views
      private EditText editTextEmail;
    private EditText editTextPassword;
    private EditText editTextPhone;
    private EditText editTextConfirmOtp;
    private AppCompatButton buttonRegister;
    private AppCompatButton buttonConfirm;
    //Volley RequestQueue
    private RequestQueue requestQueue;
    //String variables to hold email, password and phone number
    private String username;
    private String password;
    private String phone;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Initializing Views
        editTextEmail = (EditText) findViewById(R.id.editTextEmail);
        editTextPassword = (EditText) findViewById(R.id.editTextPassword);
        editTextPhone = (EditText) findViewById(R.id.editTextPhone);
        buttonRegister = (AppCompatButton) findViewById(R.id.buttonRegister);
       //Initializing the RequestQueue
        requestQueue = Volley.newRequestQueue(this);
       //Adding a listener to button
        buttonRegister.setOnClickListener((View.OnClickListener) this);
    }
//    This method would confirm the OTP
    private void confirmOtp() throws JSONException {
        //Creating a Layout Inflater object for the dialog box
        LayoutInflater li = LayoutInflater.from(this);
        //Creating a view to get the dialog box
        View confirmDialog = li.inflate(R.layout.dialog_confirm, null);
//        Initialing confirm button for dialog box and edittext of dialog box
        buttonConfirm = (AppCompatButton) confirmDialog.findViewById(R.id.buttonConfirm);
        editTextConfirmOtp = (EditText) confirmDialog.findViewById(R.id.editTextOtp);
        //Creating an alert dialog builder
        AlertDialog.Builder alert = new AlertDialog.Builder(this);
        //Adding our dialog box to the view of alert dialog
        alert.setView(confirmDialog);
        //Creating an alert dialog
        final AlertDialog alertDialog = alert.create();
        //Displaying the alert dialog
        alertDialog.show();
//        Onclick of the confirm button from alert dialog
        buttonConfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Hiding the alert dialog
                alertDialog.dismiss();
                //Displaying a progressbar
                final ProgressDialog loading = ProgressDialog.show(MainActivity.this, "Authenticating ", "Please wait while we check the entered code", false, false);
                //Getting the user entered otp from edittext
                final String otp = editTextConfirmOtp.getText().toString().trim();
                //Creating an string request
                StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.CONFIRM_URL,
                        new Response.Listener<String>() {
                            @Override
                            public void onResponse(String response) {
                                if (response.equalsIgnoreCase("success")) {
                                    loading.dismiss();
                                    //Start a new activity
                                    startActivity(new Intent(MainActivity.this, Success.class));
                                } else {
                                    //Displaying a toast if the otp entered is wrong
                                    Toast.makeText(MainActivity.this, "Wrong OTP Please try Again", Toast.LENGTH_LONG).show();
                                    try {
                                        //Asking user to enter otp again
                                        confirmOtp();
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        },
                        new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {
                                alertDialog.dismiss();
                             }
                        }){
                    @Override
                    protected Map<String, String> getParams() throws AuthFailureError {
                        Map<String, String> params = new HashMap<String, String>();
                        //Adding the parameters otp and email
                        params.put(Config.KEY_OTP, otp);
                        params.put(Config.KEY_USERNAME, username);
                        return  params;
                    }
                };
                //Adding the request to the queue
                requestQueue.add(stringRequest);
            }
        });
    }

    //this method will get register the user
    private void register() {
        //Displaying a progress dialog
        final ProgressDialog loading = ProgressDialog.show(this, "Registering", "Please wait...", false, false);
        //Getting user data
        username = editTextEmail.getText().toString().trim();
        password = editTextPassword.getText().toString().trim();
        phone = editTextPhone.getText().toString().trim();
        //Again creating the request
        StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.REGISTER_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        loading.dismiss();
                        try {
                            //Creating the json object from the response
                            JSONObject jsonResponse = new JSONObject(response);
                            //IF it is success
                            if (jsonResponse.getString(Config.TAG_RESPONSE).equalsIgnoreCase("success")) {
                                //Asking user to confirm otp
                                confirmOtp();
                            } else {
                                //If not successful user may already have registerd
                                Toast.makeText(MainActivity.this, "Username or Phone Number already registered", Toast.LENGTH_LONG).show();
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        loading.dismiss();
                        Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_LONG).show();
                    }
                }) {
            @Override
            protected Map<String, String> getParams()throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                //Adding the params to the request
                params.put(Config.KEY_USERNAME, username);
                params.put(Config.KEY_PASSWORD, password);
                params.put(Config.KEY_PHONE, phone);
                return params;
            }
        };
        //Adding request to the queue
        requestQueue.add(stringRequest);
    }
    @Override
    public void onClick(View v){
        //calling refgister method on register button click
        register();
    }
}

和配置.java

public class Config {
    public static final String REGISTER_URL = "http://192.168.0.4/famous/register.php";
    public static final String CONFIRM_URL = "http://192.168.0.4/famous/confirm.php";
    //Keys to send username, password, phone and otp
    public static final String KEY_USERNAME = "username";
    public static final String KEY_PASSWORD = "password";
    public static final String KEY_PHONE = "phone";
    public static final String KEY_OTP = "otp";
    //JSON Tag from response from server
    public static final String TAG_RESPONSE= "ErrorMessage";
}

我的 gradle 文件包含的依赖项是:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'com.android.support:design:26.1.0'
    compile 'com.mcxiaoke.volley:library:1.0.19'
}

和我使用的PHP文件注册.php

<?php
// Constants for our API
// this is applicable only when you are using SMS API
define('SMSUSER', $_POST[username]);
define('PASSWORD', $_POST[password]);
define('PHONE', $_POST[phone]);
// define('SENDERID', 'EDCRTZ');
// This function will send the otp

$otp = int rand(100000, 999999);
    // This is the sms text that will be sent via sms
$sms_content = "Welcome ".SMSUSER.", to DEMO Tp RTA app: Your verification code is".$otp ;
// This is the Actual API URL concatnated with required values
     $api_url ="http://mymessageapi".$sms_content."&senderId=EDCRTZ&routeId=1&mobileNos=".PHONE."&smsContentType=english";

//Envoking the API url and getting the response
$response = file_get_contents($api_url);
//Returning the response
return $response;
//If a past request comes to this script
if ($_SERVER['REQUEST_METHOD']=='POST') {
// getting username password and phone number
    $username = $_POST['username'];
    $password = $_POST['password'];
    $phone = $_POST['phone'];
//Generating a 6 digits OTP or verification code
$otp = rand(100000, 999999);

    //Importing the db connection script
require_once('dbConnect.php');
//Creating an SQL Query
$sql = "INSERT INTO famous (username, password, phone, otp) values('$username','$password','$phone','$otp')";
//If the query executed on the db successfully 
if (mysql_query($con,$sql)) {
    // printing the failure message in json
echo '{"ErrorMessage":"Failure"}';   
}
//Closing the databse connection
mysqli_close($con);
}
?>

确认.php

<?php
//If a post request is detected 
if ($_SERVER['REQUEST_METHOD']=='POST') {
    //gETTING THE username and otp
$username = $_POST['username'];
$otp = $_POST['otp'];

// Importing the dbConnect script
require_once('dbConnect.php');
//Creating an SQL to fetch the otp from the table
$sql = "SELECT otp FROM test-table WHERE username = '$username'";
//Getting the result array from databse 
$result = mysqli_fetch_array(mysqli_query($con,$sql));
//Getting the otp from the array 
 $realotp = $result['otp'];
//Getting the otp given is equal to otp fetched from database
if ($otp == $realotp) {
// Creating an sql query to update the column verified to 1 for the specified user
$sql = "UPDATE test-table SET verified= '1' WHERE username ='$username'";
//If the table is updated
if (mysqli_query($con,$sql)) {
        //displaying failure
echo 'success'; 
}else{
    //displaying failure
    echo "failure";
}
}else{
    //displaying failure if otp is not equal to the otp fetched from databse
    echo 'failure';
}   
//Closing the database
mysql_close($con);
}
?>

dbConnect.php 文件

<?php
 define('HOST', 'localhost');
 define('USER', 'root');
 define('PASS', '');
 define('DB', 'famous');
 //connecting to database
 $con = mysqli_connect(HOST, USER, PASS, DB) or die('Unable to Connect');
 ?>

我使用我的 WAMP for localhost 服务器在本地运行我的应用程序,我的应用程序在同一个 IP 地址上,任何可以解决这个问题的人

JSONObject jsonResponse = new JSONObject(response) 中,您正在从响应创建 JSON 对象,该对象不是有效的 JSON。

尝试在调试模式下查看response值,以确定其中的内容,以及如何获取所需的实际 JSON。

您正在 php 中打印字符串,而不是回显 json 对象

更改您的确认.php代码

//If the table is updated
if (mysqli_query($con,$sql)) {
        //displaying failure
echo 'success'; 
}else{
    //displaying failure
    echo "failure";
}
}else{
    //displaying failure if otp is not equal to the otp fetched from databse
    echo 'failure';
}   

//If the table is updated
if (mysqli_query($con,$sql)) {
        //displaying failure
echo json_encode(array('ErrorMessage'=>'success')); 
}else{
    //displaying failure
    echo json_encode(array('ErrorMessage'=>'failure')); 
}
}else{
    //displaying failure if otp is not equal to the otp fetched from databse
    echo json_encode(array('ErrorMessage'=>'failure')); 
}  

java.lang.String 无法转换为 JSONObject

问题来自

//Creating the json object from the response
 JSONObject jsonResponse = new JSONObject(response); // print response.
  • 首先确保您的response有效JSON或不。
  • DEBUG应用。 添加断点JSONObject jsonResponse

对于valid JSON情况,您可以按照 MByD's Answer .

public boolean isJSONValid(String test) {
    try {
        new JSONObject(test);
    } catch (JSONException ex) {
        try {
            new JSONArray(test);
        } catch (JSONException ex1) {
            return false;
        }
    }
    return true;
}

相关内容

最新更新