java.lang.IllegalStateException:应为 BEGIN_OBJECT,但实际为 STRING
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING
我已经编写了一个 Login
功能并与 通信 web service
我正在使用 Retrofit 但总是得到 "Failed"
获取:
retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
LoginAPI.java:
public interface LoginApi {
@FormUrlEncoded
@POST("/retrofit_user/login.php")
public void getlogin(
@Field("username") String username,
@Field("password") String password,
Callback<User> response);
}
LoginActivity.java:
restAdapter = new RestAdapter.Builder().setEndpoint(ROOT_LOGIN).build();
restAdapter.setLogLevel(RestAdapter.LogLevel.FULL);
loginApi = restAdapter.create(LoginApi.class);
buttonlogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginApi.getlogin(editTextUsername.getText().toString(),
editTextPassword.getText().toString(), new Callback<User>() {
@Override
public void success(User s, Response response) {
Toast.makeText(LoginActivity.this,"Logged In",Toast.LENGTH_LONG).show();
if(s != null) {
Log.d("name:", s.getName());
Log.d("email:", s.getEmail());
Log.d("id:", String.valueOf(s.getId()));
}
}
@Override
public void failure(RetrofitError error) {
Log.d("error:", error.toString());
Toast.makeText(LoginActivity.this,"Failed",Toast.LENGTH_LONG).show();
}
});
}
});
User.java:
public class User {
String name;
String username;
String password;
String email;
int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
日志显示
D/Retrofit: <--- HTTP 200 http://domain.info/retrofit_user/login.php (942ms)
D/Retrofit: : HTTP/1.1 200 OK
D/Retrofit: Connection: Keep-Alive
D/Retrofit: Content-Type: text/html; charset=UTF-8
D/Retrofit: Date: Sat, 20 Feb 2016 06:00:39 GMT
D/Retrofit: Keep-Alive: timeout=5, max=100
D/Retrofit: Server: Apache/2.4.16 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4
D/Retrofit: Transfer-Encoding: chunked
D/Retrofit: X-Android-Received-Millis: 1455948038590
D/Retrofit: X-Android-Response-Source: NETWORK 200
D/Retrofit: X-Android-Selected-Transport: http/1.1
D/Retrofit: X-Android-Sent-Millis: 1455948037988
D/Retrofit: X-Powered-By: PHP/5.6.14
D/Retrofit: Done
D/Retrofit: <--- END HTTP (4-byte body)
D/error:: retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
D/GraphicBuffer: create handle(0x55bb2e98) (w:256, h:66, f:1)
D/GraphicBuffer: close handle(0x55bb2e98) (w:256 h:66 f:1)
这是我的 login.php
脚本:
<?php
$objConnect = mysql_connect("localhost","username","password");
$objDB = mysql_select_db("database");
/*** for sample */
// $_POST["username"] = "sun";
// $_POST["password"] = "live";
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
$strSQL = "select * from test_users where username = '".$username."' and password = '".$password."' ";
$objQuery = mysql_query($strSQL);
$intNumRows = mysql_num_rows($objQuery);
if($intNumRows==0)
{
echo "Not Done" ;
}
else
{
echo "Done" ;
}
mysql_close($objConnect);
?>
问题是,retrofit 期望 JSON
输出可以从 login.php
放入 User
class,但是 login.php
给出的是"Not Done" 或 "Done".
您必须使您的 php 脚本输出 json 为以下格式,
{
"name": "name",
"username": "username",
"password": "password",
"email": "email",
"id": id
}
您必须编辑 php 代码。会是这样的,
<?php
$objConnect = mysql_connect("localhost","username","password");
$objDB = mysql_select_db("database");
/*** for sample */
// $_POST["username"] = "sun";
// $_POST["password"] = "live";
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
$strSQL = "select * from test_users where username = '".$username."' and password = '".$password."' ";
$objQuery = mysql_query($strSQL);
$intNumRows = mysql_num_rows($objQuery);
if($intNumRows==0)
{
$response["success"] = 0;
$response["name"] = "";
$response["username"] = "";
$response["password"] = "";
$response["email"] = "";
$response["id"] = 0;
}
else
{
$row = mysql_fetch_array($objQuery);
$response["success"] = 1;
$response["name"] = $row["name"];
$response["username"] = $row["username"];
$response["password"] = $row["password"];
$response["email"] = $row["email"];
$response["id"] = $row["id"];
}
mysql_close($objConnect);
echo json_encode($response, JSON_NUMERIC_CHECK);
?>
同时将 int success;
字段添加到 User
class 并使用它来验证输出。所以你的成功方法将是,
@Override
public void success(User s, Response response) {
if(s != null && s.getSuccess() == 1) {
Toast.makeText(LoginActivity.this,"Logged In",Toast.LENGTH_LONG).show();
Log.d("name:", s.getName());
Log.d("email:", s.getEmail());
Log.d("id:", String.valueOf(s.getId()));
} else {
Toast.makeText(LoginActivity.this,"Invalid!",Toast.LENGTH_LONG).show();
}
}
更新
id
字段是数据库中的一个 int
,但它 returns id 是一个字符串。请参阅 this 线程。在 php 中将 JSON_NUMERIC_CHECK
添加到 json_encode()
会有所帮助。
我已经编写了一个 Login
功能并与 通信 web service
我正在使用 Retrofit 但总是得到 "Failed"
获取:
retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
LoginAPI.java:
public interface LoginApi {
@FormUrlEncoded
@POST("/retrofit_user/login.php")
public void getlogin(
@Field("username") String username,
@Field("password") String password,
Callback<User> response);
}
LoginActivity.java:
restAdapter = new RestAdapter.Builder().setEndpoint(ROOT_LOGIN).build();
restAdapter.setLogLevel(RestAdapter.LogLevel.FULL);
loginApi = restAdapter.create(LoginApi.class);
buttonlogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loginApi.getlogin(editTextUsername.getText().toString(),
editTextPassword.getText().toString(), new Callback<User>() {
@Override
public void success(User s, Response response) {
Toast.makeText(LoginActivity.this,"Logged In",Toast.LENGTH_LONG).show();
if(s != null) {
Log.d("name:", s.getName());
Log.d("email:", s.getEmail());
Log.d("id:", String.valueOf(s.getId()));
}
}
@Override
public void failure(RetrofitError error) {
Log.d("error:", error.toString());
Toast.makeText(LoginActivity.this,"Failed",Toast.LENGTH_LONG).show();
}
});
}
});
User.java:
public class User {
String name;
String username;
String password;
String email;
int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
日志显示
D/Retrofit: <--- HTTP 200 http://domain.info/retrofit_user/login.php (942ms)
D/Retrofit: : HTTP/1.1 200 OK
D/Retrofit: Connection: Keep-Alive
D/Retrofit: Content-Type: text/html; charset=UTF-8
D/Retrofit: Date: Sat, 20 Feb 2016 06:00:39 GMT
D/Retrofit: Keep-Alive: timeout=5, max=100
D/Retrofit: Server: Apache/2.4.16 (Unix) OpenSSL/1.0.1e-fips mod_bwlimited/1.4
D/Retrofit: Transfer-Encoding: chunked
D/Retrofit: X-Android-Received-Millis: 1455948038590
D/Retrofit: X-Android-Response-Source: NETWORK 200
D/Retrofit: X-Android-Selected-Transport: http/1.1
D/Retrofit: X-Android-Sent-Millis: 1455948037988
D/Retrofit: X-Powered-By: PHP/5.6.14
D/Retrofit: Done
D/Retrofit: <--- END HTTP (4-byte body)
D/error:: retrofit.RetrofitError: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
D/GraphicBuffer: create handle(0x55bb2e98) (w:256, h:66, f:1)
D/GraphicBuffer: close handle(0x55bb2e98) (w:256 h:66 f:1)
这是我的 login.php
脚本:
<?php
$objConnect = mysql_connect("localhost","username","password");
$objDB = mysql_select_db("database");
/*** for sample */
// $_POST["username"] = "sun";
// $_POST["password"] = "live";
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
$strSQL = "select * from test_users where username = '".$username."' and password = '".$password."' ";
$objQuery = mysql_query($strSQL);
$intNumRows = mysql_num_rows($objQuery);
if($intNumRows==0)
{
echo "Not Done" ;
}
else
{
echo "Done" ;
}
mysql_close($objConnect);
?>
问题是,retrofit 期望 JSON
输出可以从 login.php
放入 User
class,但是 login.php
给出的是"Not Done" 或 "Done".
您必须使您的 php 脚本输出 json 为以下格式,
{
"name": "name",
"username": "username",
"password": "password",
"email": "email",
"id": id
}
您必须编辑 php 代码。会是这样的,
<?php
$objConnect = mysql_connect("localhost","username","password");
$objDB = mysql_select_db("database");
/*** for sample */
// $_POST["username"] = "sun";
// $_POST["password"] = "live";
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
$strSQL = "select * from test_users where username = '".$username."' and password = '".$password."' ";
$objQuery = mysql_query($strSQL);
$intNumRows = mysql_num_rows($objQuery);
if($intNumRows==0)
{
$response["success"] = 0;
$response["name"] = "";
$response["username"] = "";
$response["password"] = "";
$response["email"] = "";
$response["id"] = 0;
}
else
{
$row = mysql_fetch_array($objQuery);
$response["success"] = 1;
$response["name"] = $row["name"];
$response["username"] = $row["username"];
$response["password"] = $row["password"];
$response["email"] = $row["email"];
$response["id"] = $row["id"];
}
mysql_close($objConnect);
echo json_encode($response, JSON_NUMERIC_CHECK);
?>
同时将 int success;
字段添加到 User
class 并使用它来验证输出。所以你的成功方法将是,
@Override
public void success(User s, Response response) {
if(s != null && s.getSuccess() == 1) {
Toast.makeText(LoginActivity.this,"Logged In",Toast.LENGTH_LONG).show();
Log.d("name:", s.getName());
Log.d("email:", s.getEmail());
Log.d("id:", String.valueOf(s.getId()));
} else {
Toast.makeText(LoginActivity.this,"Invalid!",Toast.LENGTH_LONG).show();
}
}
更新
id
字段是数据库中的一个 int
,但它 returns id 是一个字符串。请参阅 this 线程。在 php 中将 JSON_NUMERIC_CHECK
添加到 json_encode()
会有所帮助。