com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期 BEGIN_OBJECT 但在第 2 行第 2 列路径 $ while UPDATE 时为 STRING
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 2 column 2 path $ while UPDATE
您好,我正在创建一个 android 应用程序,供学生轻松找到住宿的房间,作为一个学校项目,我在更新方面遇到了一些问题。我用 000webhost.com 创建了一个网络服务。我已经知道 put 和 Delete 是付费的,但我的老师告诉我们我们可以将它嵌入 POST 并使其工作。
通过这种方式,我已经能够让我的 DELETE 发挥作用。但是我在更新时遇到了麻烦。当我尝试更新时,所有数据都更改为我想要更改的内容,但是同时调用了我的 OnFailure 方法,它给了我这个错误:com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT 但在第 2 行第 2 列路径 $
是 STRING
我觉得很奇怪,因为在我的活动中,我使用了与我的 POST 相似的代码(完美运行),尽管有错误,我的数据已更新,但我想消除错误,因为它不允许我按预期更改 activity。
这是我嵌入在 POST 中的 webService PUT(为 web 服务使用了 slim 4 和 NOTORM)
//Put anuncios
$app->post('/api/editar_anuncios/{id}', function( $request, $response){
require_once('db/dbconnection.php');
$id = $request->getAttribute('id');
$users_id = $request->getParsedBody()["users_id"];
$morada = $request->getParsedBody()["morada"];
$n_quartos = $request->getParsedBody()["n_quartos"];
$latitude = $request->getParsedBody()["latitude"];
$longitude = $request->getParsedBody()["longitude"];
$fotografia = $request->getParsedBody()["fotografia"];
$preco = $request->getParsedBody()["preco"];
$ncasas_banho = $request->getParsedBody()["ncasas_banho"];
$telemovel = $request->getParsedBody()["telemovel"];
$mobilado= $request->getParsedBody()["mobilado"];
$outros_atributos = $request->getParsedBody()["outros_atributos"];
$qrcode = $request->getParsedBody()["qrcode"];
$data = array(
"users_id"=> $users_id,
"morada" => $morada,
"n_quartos" => $n_quartos,
"latitude" => $latitude,
"longitude" => $longitude,
"fotografia"=> $fotografia,
"preco" => $preco,
"ncasas_banho" => $ncasas_banho,
"telemovel" => $telemovel,
"mobilado" => $mobilado,
"outros_atributos" => $outros_atributos,
"qrcode" => $qrcode
);
if(isset($db->anuncios[$id])){
$result = $db->anuncios[$id]->update($data);
if($result){
echo json_encode('O anuncio foi atualizado com sucesso', JSON_UNESCAPED_UNICODE);
return $response;
} else
echo json_encode('A atualização falhou', JSON_UNESCAPED_UNICODE);
return $response;
} else
echo json_encode('O anuncio não existe', JSON_UNESCAPED_UNICODE);
return $response;
});
我的端点
@FormUrlEncoded
@POST("editar_anuncios/{id}")
fun editar(@Path("id") id: Int?,
@Field("users_id") users_id: Int?,
@Field("morada") morada: String?,
@Field("n_quartos") n_quartos: Int?,
@Field("latitude") latitude: Double?,
@Field("longitude") longitude: Double?,
@Field("fotografia") fotografia: String?,
@Field("preco") preco: Double?,
@Field("ncasas_banho") ncasas_banho: Int?,
@Field("telemovel") telemovel: String?,
@Field("mobilado") mobilado: String?,
@Field("outros_atributos") outros_atributos: String?,
@Field("qrcode") qrcode: String?): Call<OutputEditar>
我的 ServiceBuilder
object ServiceBuilder {
private val client = OkHttpClient.Builder().build()
private val retrofit = Retrofit.Builder()
.baseUrl("https://tneveda.000webhostapp.com/RoomForStudents/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
fun<T> buildService(service: Class<T>): T {
return retrofit.create(service)
}
}
我的输出编辑器
data class OutputEditar(
val users_id: Int,
val morada: String,
val n_quartos: Int,
val latitude: Double,
val longitude: Double,
val fotografia: String,
val preco: Double,
val ncasas_banho: Int,
val telemovel: String,
val mobilado: String,
val outros_atributos: String,
val qrcode: String,
val status: String,
val MSG: String
)
我的Activity更新最重要的代码。在 OnCreate 上,我调用网络服务将预期数据放在我的视图中,并且它运行良好。只是放在这里,以显示我如何获取要在我的更新方法中使用的变量
private lateinit var editMoradaView: EditText
private lateinit var editNQuartosView: EditText
private lateinit var shared_preferences: SharedPreferences
private lateinit var latitude : EditText
private lateinit var longitude : EditText
private lateinit var imageView: ImageView
private lateinit var button: Button
private val pickImage = 100
private var imageUri: Uri? = null
private var base64:String? =null
private var fotografia:String? =null
private lateinit var decodedByte: Bitmap
private var isBitMap:Boolean= false
private var ID:Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_editar_menu)
imageView = findViewById(R.id.preview)
button = findViewById(R.id.upload)
editMoradaView = findViewById(R.id.morada)
editNQuartosView = findViewById(R.id.nquartos)
latitude = findViewById(R.id.latitude)
longitude = findViewById(R.id.longitude)
button.setOnClickListener {
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
startActivityForResult(gallery, pickImage)
}
shared_preferences = getSharedPreferences("shared_preferences", Context.MODE_PRIVATE)
val isLogin = shared_preferences.getBoolean("login",false )
setTitle(R.string.edit)
var id = intent.getStringExtra(DetalhesActivity.PARAM_ID)
val request = ServiceBuilder.buildService(EndPoints::class.java)
val call : Call<List<Anuncio>> = request.getAnunciosById2(id)
call.enqueue(object : Callback<List<Anuncio>> {
override fun onResponse(call: Call<List<Anuncio>>, response: Response<List<Anuncio>>) {
if (response.isSuccessful) {
anuncios = response.body()!!
for (anuncio in anuncios) {
editMoradaView.setText(anuncio.morada)
editNQuartosView.setText(anuncio.n_quartos.toString())
latitude.setText(anuncio.latitude.toString())
longitude.setText(anuncio.longitude.toString())
ID = anuncio.id
val decodedString: ByteArray = Base64.decode(anuncio.fotografia, Base64.DEFAULT)
decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
imageView.setImageBitmap(decodedByte)
isBitMap= true
}
}
}
override fun onFailure(call: Call<List<Anuncio>>, t: Throwable) {
Toast.makeText(this@EditarAnuncio,"${t.message}", Toast.LENGTH_LONG).show()
}
})
}
我的更新方法,我检查文件是否是位图,因为当我从 phone 中选择图片时,我将其更改为位图,然后更改为 base64 字符串,然后以这种方式插入在我的数据库上。但是当我从数据库中获取图片以将其显示在我的 ImageView 上时,我将其从 base64 更改为仅位图并以该格式显示在屏幕上。所以我必须检查我的文件是哪种格式,以正确更新它(它按我的预期工作,因为如果我尝试更改它,图片会更新)。我尝试更改默认值以测试是否所有内容都更新,并且所有内容都按预期更新。但是它仍然传递来自 onFailure 方法的错误,我不明白为什么会发生这种情况,以及我可以做些什么来使错误消失。谢谢
fun editar(view: View) {
val request = ServiceBuilder.buildService(EndPoints::class.java)
val latitude = latitude.text.toString().toDouble()
val longitude = longitude.text.toString().toDouble()
val morada= editMoradaView.text.toString()
val n_quartos = editNQuartosView.text.toString().toInt()
val utilizador_id = shared_preferences.getInt("id", 0)
if(isBitMap){
val base = getBase64String(decodedByte)
fotografia = base
}
else{
fotografia = base64
}
val call = request.editar(
id = ID,
users_id = utilizador_id,
morada = morada,
n_quartos = n_quartos,
latitude = latitude.toString().toDouble(),
longitude = longitude.toString().toDouble(),
fotografia = fotografia,
preco = 21.0,
ncasas_banho = 4,
telemovel= "teste3",
mobilado = "teste3",
outros_atributos = "2",
qrcode = "teste3")
call.enqueue(object : Callback<OutputEditar> {
override fun onResponse(call: Call<OutputEditar>, response: Response<OutputEditar>){
if (response.isSuccessful){
val c: OutputEditar = response.body()!!
Toast.makeText(this@EditarAnuncio, c.MSG, Toast.LENGTH_LONG).show()
val intent = Intent(this@EditarAnuncio, MapsActivity::class.java)
startActivity(intent)
finish()
}
}
override fun onFailure(call: Call<OutputEditar>, t: Throwable){
Toast.makeText(this@EditarAnuncio,"${t.message}", Toast.LENGTH_SHORT).show()
}
})
}
编辑:
我尝试通过像这样放置 Json 在 Postman 中测试我的更新,它在 Postman 中有效。但是在我的应用程序中它仍然无法正常工作。我不明白我在我的应用程序中没有使用这种格式(看起来是这样)
但是当我尝试在我的数据库中插入数据时(我的代码与更新类似)它可以正常工作而没有任何错误。在我的更新中它有效但不是 100%,因为它仍然给我错误
{
"users_id": 1,
"n_quartos": 2,
"latitude": 20.0,
"longitude": 2.0,
"morada": "teste",
"fotografia": "teste",
"preco": 240,
"ncasas_banho": 4,
"telemovel": 9242424242,
"mobilado": "teste",
"outros_atributos": "teste",
"qrcode": "teste"
}
终于解决了我的Issue,问题有点是我自己没注意。由于我的数据正在更新,这意味着我正在从我的网络服务中获得响应,但在某些时候它导致了该错误,所以我猜我在应用程序上的代码可能都是正确的,问题出在网络服务内部,而 Bingo
因为我在我的 OutputEditar 中放入了变量 MSG 和状态,所以它期望在我的网络服务上找到它们。我在我的所有帖子和删除中都定义了它们,但我忘了在我的放置中添加它们,所以我在端点的末尾添加了它们,现在它可以正常工作了。
$app->post('/api/editar_anuncios/{id}', function( $request, $response){
require_once('db/dbconnection.php');
$id = $request->getAttribute('id');
$users_id = $request->getParsedBody()["users_id"];
$morada = $request->getParsedBody()["morada"];
$n_quartos = $request->getParsedBody()["n_quartos"];
$latitude = $request->getParsedBody()["latitude"];
$longitude = $request->getParsedBody()["longitude"];
$fotografia = $request->getParsedBody()["fotografia"];
$preco = $request->getParsedBody()["preco"];
$ncasas_banho = $request->getParsedBody()["ncasas_banho"];
$telemovel = $request->getParsedBody()["telemovel"];
$mobilado= $request->getParsedBody()["mobilado"];
$outros_atributos = $request->getParsedBody()["outros_atributos"];
$qrcode = $request->getParsedBody()["qrcode"];
$data = array(
"users_id"=> $users_id,
"morada" => $morada,
"n_quartos" => $n_quartos,
"latitude" => $latitude,
"longitude" => $longitude,
"fotografia"=> $fotografia,
"preco" => $preco,
"ncasas_banho" => $ncasas_banho,
"telemovel" => $telemovel,
"mobilado" => $mobilado,
"outros_atributos" => $outros_atributos,
"qrcode" => $qrcode
);
if(isset($db->anuncios[$id])){
$result = $db->anuncios[$id]->update($data);
if($result){
$result = ['status' => true, 'MSG' => "Anúncio atualizado!"];
echo json_encode($result, JSON_UNESCAPED_UNICODE);
return $response;
} else
$result = ['status' => false, 'MSG' => "Erro na atualizacao do anúncio!"];
echo json_encode($result, JSON_UNESCAPED_UNICODE);
return $response;
} else
$result = ['status' => false, 'MSG' => "O Anúncio nao existe!"];
echo json_encode($result, JSON_UNESCAPED_UNICODE);
return $response;
});
您好,我正在创建一个 android 应用程序,供学生轻松找到住宿的房间,作为一个学校项目,我在更新方面遇到了一些问题。我用 000webhost.com 创建了一个网络服务。我已经知道 put 和 Delete 是付费的,但我的老师告诉我们我们可以将它嵌入 POST 并使其工作。
通过这种方式,我已经能够让我的 DELETE 发挥作用。但是我在更新时遇到了麻烦。当我尝试更新时,所有数据都更改为我想要更改的内容,但是同时调用了我的 OnFailure 方法,它给了我这个错误:com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT 但在第 2 行第 2 列路径 $
是 STRING我觉得很奇怪,因为在我的活动中,我使用了与我的 POST 相似的代码(完美运行),尽管有错误,我的数据已更新,但我想消除错误,因为它不允许我按预期更改 activity。
这是我嵌入在 POST 中的 webService PUT(为 web 服务使用了 slim 4 和 NOTORM)
//Put anuncios
$app->post('/api/editar_anuncios/{id}', function( $request, $response){
require_once('db/dbconnection.php');
$id = $request->getAttribute('id');
$users_id = $request->getParsedBody()["users_id"];
$morada = $request->getParsedBody()["morada"];
$n_quartos = $request->getParsedBody()["n_quartos"];
$latitude = $request->getParsedBody()["latitude"];
$longitude = $request->getParsedBody()["longitude"];
$fotografia = $request->getParsedBody()["fotografia"];
$preco = $request->getParsedBody()["preco"];
$ncasas_banho = $request->getParsedBody()["ncasas_banho"];
$telemovel = $request->getParsedBody()["telemovel"];
$mobilado= $request->getParsedBody()["mobilado"];
$outros_atributos = $request->getParsedBody()["outros_atributos"];
$qrcode = $request->getParsedBody()["qrcode"];
$data = array(
"users_id"=> $users_id,
"morada" => $morada,
"n_quartos" => $n_quartos,
"latitude" => $latitude,
"longitude" => $longitude,
"fotografia"=> $fotografia,
"preco" => $preco,
"ncasas_banho" => $ncasas_banho,
"telemovel" => $telemovel,
"mobilado" => $mobilado,
"outros_atributos" => $outros_atributos,
"qrcode" => $qrcode
);
if(isset($db->anuncios[$id])){
$result = $db->anuncios[$id]->update($data);
if($result){
echo json_encode('O anuncio foi atualizado com sucesso', JSON_UNESCAPED_UNICODE);
return $response;
} else
echo json_encode('A atualização falhou', JSON_UNESCAPED_UNICODE);
return $response;
} else
echo json_encode('O anuncio não existe', JSON_UNESCAPED_UNICODE);
return $response;
});
我的端点
@FormUrlEncoded
@POST("editar_anuncios/{id}")
fun editar(@Path("id") id: Int?,
@Field("users_id") users_id: Int?,
@Field("morada") morada: String?,
@Field("n_quartos") n_quartos: Int?,
@Field("latitude") latitude: Double?,
@Field("longitude") longitude: Double?,
@Field("fotografia") fotografia: String?,
@Field("preco") preco: Double?,
@Field("ncasas_banho") ncasas_banho: Int?,
@Field("telemovel") telemovel: String?,
@Field("mobilado") mobilado: String?,
@Field("outros_atributos") outros_atributos: String?,
@Field("qrcode") qrcode: String?): Call<OutputEditar>
我的 ServiceBuilder
object ServiceBuilder {
private val client = OkHttpClient.Builder().build()
private val retrofit = Retrofit.Builder()
.baseUrl("https://tneveda.000webhostapp.com/RoomForStudents/api/")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
fun<T> buildService(service: Class<T>): T {
return retrofit.create(service)
}
}
我的输出编辑器
data class OutputEditar(
val users_id: Int,
val morada: String,
val n_quartos: Int,
val latitude: Double,
val longitude: Double,
val fotografia: String,
val preco: Double,
val ncasas_banho: Int,
val telemovel: String,
val mobilado: String,
val outros_atributos: String,
val qrcode: String,
val status: String,
val MSG: String
)
我的Activity更新最重要的代码。在 OnCreate 上,我调用网络服务将预期数据放在我的视图中,并且它运行良好。只是放在这里,以显示我如何获取要在我的更新方法中使用的变量
private lateinit var editMoradaView: EditText
private lateinit var editNQuartosView: EditText
private lateinit var shared_preferences: SharedPreferences
private lateinit var latitude : EditText
private lateinit var longitude : EditText
private lateinit var imageView: ImageView
private lateinit var button: Button
private val pickImage = 100
private var imageUri: Uri? = null
private var base64:String? =null
private var fotografia:String? =null
private lateinit var decodedByte: Bitmap
private var isBitMap:Boolean= false
private var ID:Int = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_editar_menu)
imageView = findViewById(R.id.preview)
button = findViewById(R.id.upload)
editMoradaView = findViewById(R.id.morada)
editNQuartosView = findViewById(R.id.nquartos)
latitude = findViewById(R.id.latitude)
longitude = findViewById(R.id.longitude)
button.setOnClickListener {
val gallery = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
startActivityForResult(gallery, pickImage)
}
shared_preferences = getSharedPreferences("shared_preferences", Context.MODE_PRIVATE)
val isLogin = shared_preferences.getBoolean("login",false )
setTitle(R.string.edit)
var id = intent.getStringExtra(DetalhesActivity.PARAM_ID)
val request = ServiceBuilder.buildService(EndPoints::class.java)
val call : Call<List<Anuncio>> = request.getAnunciosById2(id)
call.enqueue(object : Callback<List<Anuncio>> {
override fun onResponse(call: Call<List<Anuncio>>, response: Response<List<Anuncio>>) {
if (response.isSuccessful) {
anuncios = response.body()!!
for (anuncio in anuncios) {
editMoradaView.setText(anuncio.morada)
editNQuartosView.setText(anuncio.n_quartos.toString())
latitude.setText(anuncio.latitude.toString())
longitude.setText(anuncio.longitude.toString())
ID = anuncio.id
val decodedString: ByteArray = Base64.decode(anuncio.fotografia, Base64.DEFAULT)
decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
imageView.setImageBitmap(decodedByte)
isBitMap= true
}
}
}
override fun onFailure(call: Call<List<Anuncio>>, t: Throwable) {
Toast.makeText(this@EditarAnuncio,"${t.message}", Toast.LENGTH_LONG).show()
}
})
}
我的更新方法,我检查文件是否是位图,因为当我从 phone 中选择图片时,我将其更改为位图,然后更改为 base64 字符串,然后以这种方式插入在我的数据库上。但是当我从数据库中获取图片以将其显示在我的 ImageView 上时,我将其从 base64 更改为仅位图并以该格式显示在屏幕上。所以我必须检查我的文件是哪种格式,以正确更新它(它按我的预期工作,因为如果我尝试更改它,图片会更新)。我尝试更改默认值以测试是否所有内容都更新,并且所有内容都按预期更新。但是它仍然传递来自 onFailure 方法的错误,我不明白为什么会发生这种情况,以及我可以做些什么来使错误消失。谢谢
fun editar(view: View) {
val request = ServiceBuilder.buildService(EndPoints::class.java)
val latitude = latitude.text.toString().toDouble()
val longitude = longitude.text.toString().toDouble()
val morada= editMoradaView.text.toString()
val n_quartos = editNQuartosView.text.toString().toInt()
val utilizador_id = shared_preferences.getInt("id", 0)
if(isBitMap){
val base = getBase64String(decodedByte)
fotografia = base
}
else{
fotografia = base64
}
val call = request.editar(
id = ID,
users_id = utilizador_id,
morada = morada,
n_quartos = n_quartos,
latitude = latitude.toString().toDouble(),
longitude = longitude.toString().toDouble(),
fotografia = fotografia,
preco = 21.0,
ncasas_banho = 4,
telemovel= "teste3",
mobilado = "teste3",
outros_atributos = "2",
qrcode = "teste3")
call.enqueue(object : Callback<OutputEditar> {
override fun onResponse(call: Call<OutputEditar>, response: Response<OutputEditar>){
if (response.isSuccessful){
val c: OutputEditar = response.body()!!
Toast.makeText(this@EditarAnuncio, c.MSG, Toast.LENGTH_LONG).show()
val intent = Intent(this@EditarAnuncio, MapsActivity::class.java)
startActivity(intent)
finish()
}
}
override fun onFailure(call: Call<OutputEditar>, t: Throwable){
Toast.makeText(this@EditarAnuncio,"${t.message}", Toast.LENGTH_SHORT).show()
}
})
}
编辑:
我尝试通过像这样放置 Json 在 Postman 中测试我的更新,它在 Postman 中有效。但是在我的应用程序中它仍然无法正常工作。我不明白我在我的应用程序中没有使用这种格式(看起来是这样)
但是当我尝试在我的数据库中插入数据时(我的代码与更新类似)它可以正常工作而没有任何错误。在我的更新中它有效但不是 100%,因为它仍然给我错误
{
"users_id": 1,
"n_quartos": 2,
"latitude": 20.0,
"longitude": 2.0,
"morada": "teste",
"fotografia": "teste",
"preco": 240,
"ncasas_banho": 4,
"telemovel": 9242424242,
"mobilado": "teste",
"outros_atributos": "teste",
"qrcode": "teste"
}
终于解决了我的Issue,问题有点是我自己没注意。由于我的数据正在更新,这意味着我正在从我的网络服务中获得响应,但在某些时候它导致了该错误,所以我猜我在应用程序上的代码可能都是正确的,问题出在网络服务内部,而 Bingo
因为我在我的 OutputEditar 中放入了变量 MSG 和状态,所以它期望在我的网络服务上找到它们。我在我的所有帖子和删除中都定义了它们,但我忘了在我的放置中添加它们,所以我在端点的末尾添加了它们,现在它可以正常工作了。
$app->post('/api/editar_anuncios/{id}', function( $request, $response){
require_once('db/dbconnection.php');
$id = $request->getAttribute('id');
$users_id = $request->getParsedBody()["users_id"];
$morada = $request->getParsedBody()["morada"];
$n_quartos = $request->getParsedBody()["n_quartos"];
$latitude = $request->getParsedBody()["latitude"];
$longitude = $request->getParsedBody()["longitude"];
$fotografia = $request->getParsedBody()["fotografia"];
$preco = $request->getParsedBody()["preco"];
$ncasas_banho = $request->getParsedBody()["ncasas_banho"];
$telemovel = $request->getParsedBody()["telemovel"];
$mobilado= $request->getParsedBody()["mobilado"];
$outros_atributos = $request->getParsedBody()["outros_atributos"];
$qrcode = $request->getParsedBody()["qrcode"];
$data = array(
"users_id"=> $users_id,
"morada" => $morada,
"n_quartos" => $n_quartos,
"latitude" => $latitude,
"longitude" => $longitude,
"fotografia"=> $fotografia,
"preco" => $preco,
"ncasas_banho" => $ncasas_banho,
"telemovel" => $telemovel,
"mobilado" => $mobilado,
"outros_atributos" => $outros_atributos,
"qrcode" => $qrcode
);
if(isset($db->anuncios[$id])){
$result = $db->anuncios[$id]->update($data);
if($result){
$result = ['status' => true, 'MSG' => "Anúncio atualizado!"];
echo json_encode($result, JSON_UNESCAPED_UNICODE);
return $response;
} else
$result = ['status' => false, 'MSG' => "Erro na atualizacao do anúncio!"];
echo json_encode($result, JSON_UNESCAPED_UNICODE);
return $response;
} else
$result = ['status' => false, 'MSG' => "O Anúncio nao existe!"];
echo json_encode($result, JSON_UNESCAPED_UNICODE);
return $response;
});