改装响应为空,错误的数据类实现?
retrofit response null, wrong dataclass implementation?
我正在尝试使用此 api 响应将“响应”json 对象添加到我的登录 api,
一切都在它旁边。
{
"user": {
"id": 1,
"name": "lee",
"lastname": "doe",
"email": "lee@doe.com",
"email_verified_at": null,
"role_id": 3,
"created_at": null,
"updated_at": null
},
"token": "18|XlZE6z4jyibRoRhVRgGuSJyheyIsz8tyBT7Dz0R9",
"response": {
"error": "false", //return always null on retrofit
"message": "Accesso effettuato" //return always null on retrofit
}
}
我用于管理数据的数据class:
Venditore.kt
data class Venditore (
val user: User?=null,
val token: String?=null,
val response:ApiRresponse?=null
)
data class User (
val id: Int?=null,
val name: String?=null,
val password:String?=null,
val lastname:String?=null,
val email: String?=null,
val role_id:Int?=null,
val email_verified_at: Any? = null,
val created_at: Any? = null,
val updated_at: Any? = null
)
data class ApiRresponse(
val error:String?=null,
val message:String?=null
)
如果我尝试登录,它工作正常,但一直如此
response.body()?.response?.message
return 空
我该如何解决?
编辑 1
不能为空,因为我不是在获取数据,而是在传递设置的信息,
我也认为这可能是后端问题,但我已经在 Postman 上进行了测试,并且始终 return 正确的格式(实际上是我在上面发布的 JSON)
后端
class UserController extends Controller
{
function index(Request $request)
{
$rules = array(
'email' =>'required',
'password' =>'required'
);
$messages = [
'email.required'=> 'email mancante',
'password.required'=> 'password mancante'
];
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)){
$validator = Validator::make($request->all(),$rules,$messages);
if($validator->fails()){
$text_message = $validator->errors()->first();
$response = [
'response'=>[
'error' => 'true',
'message' => $text_message
]
];
return response($response,400);
}
else
{
$response = [
'response'=>[
'error' => 'true',
'message' => 'le credenziali non sono corrette'
]
];
return response($response,401);
}
}
$token = $user->createToken($request->device_name)->plainTextToken;
$APiresponse = [
'error' => 'false',
'message' => 'Accesso effettuato'
];
$response=['user'=> $user,
'token' =>$token,
'response' => $APiresponse
];
return response($response, 201);
}
改装电话
fun login(){
var email :String = txtEmailUser.text.toString()
var password :String = txtPasswordUser.text.toString()
var deviceName = android.os.Build.MODEL
mServiceV = Common.apiV
Log.d("response", deviceName)
mServiceV.login(email,password,deviceName).enqueue(object : Callback<Venditore> {
override fun onResponse(call: Call<Venditore>, response: Response<Venditore>) {
Log.d("code",response.code().toString())
Log.d("response",response.body().toString())
when(response.code()) {
400->{
Toast.makeText(
this@MainActivity,
response.body()?.response?.message,
Toast.LENGTH_SHORT
).show()
return
}
401 -> {
Toast.makeText(
this@MainActivity,
response.body()?.response?.message,
Toast.LENGTH_SHORT
).show()
return
}
201->{
GlobalVar.Myid = response.body()?.user?.id
GlobalVar.MyT = response.body()?.token
Toast.makeText(this@MainActivity, response.body()?.response?.message, Toast.LENGTH_SHORT).show()
startActivity(Intent(this@MainActivity, MagazzinoActivity::class.java))
}
else->{
if (!response.isSuccessful) {
Toast.makeText(
this@MainActivity,
"Qualcosa è andato storto",
Toast.LENGTH_SHORT
).show()
Log.d("heades", response.code().toString())
return
}
}
}
}
override fun onFailure(call: Call<Venditore>, t: Throwable) {
Toast.makeText(this@MainActivity, t.message!!, Toast.LENGTH_SHORT).show()
}
})
}
更新
response.body()?.response?.message 在登录成功时工作,对不起,我以为不是
问题
如果是 400 或 401 代码,我的 api 响应只是
"response": {
"error": "true",
"message": "le credenziali non sono corrette"
}
可能是这个问题,我还应该 return 这种格式吗?
{
"user": {
"id": null,
"name": "null",
"lastname": "null",
"email": "null",
"email_verified_at": null,
"role_id": null,
"created_at": null,
"updated_at": null
},
"token": "null",
"response": {
"error": "false",
"message": "some message"
}
}
终于解决了!
希望这对我身边的人有所帮助。
当调用 4xx 代码时 response.body() 为空而不是 response.errorBody(),
因此所有 API 响应都将存在(如果您设置自定义 4xx 代码)或默认服务器响应。
理解后我还发现Retrofit不会像Body()那样转换errorBody()所以你应该自己转换。
解决方案
val gson = Gson()
val type = object : TypeToken<APIresponse>() {}.type
var errorResponse: APIresponse? = gson.fromJson(response.errorBody()!!.charStream(), type)
//Retriving just message
Toast.makeText(this@MainActivity, errorResponse?.message, Toast.LENGTH_SHORT).show()
我正在尝试使用此 api 响应将“响应”json 对象添加到我的登录 api, 一切都在它旁边。
{
"user": {
"id": 1,
"name": "lee",
"lastname": "doe",
"email": "lee@doe.com",
"email_verified_at": null,
"role_id": 3,
"created_at": null,
"updated_at": null
},
"token": "18|XlZE6z4jyibRoRhVRgGuSJyheyIsz8tyBT7Dz0R9",
"response": {
"error": "false", //return always null on retrofit
"message": "Accesso effettuato" //return always null on retrofit
}
}
我用于管理数据的数据class:
Venditore.kt
data class Venditore (
val user: User?=null,
val token: String?=null,
val response:ApiRresponse?=null
)
data class User (
val id: Int?=null,
val name: String?=null,
val password:String?=null,
val lastname:String?=null,
val email: String?=null,
val role_id:Int?=null,
val email_verified_at: Any? = null,
val created_at: Any? = null,
val updated_at: Any? = null
)
data class ApiRresponse(
val error:String?=null,
val message:String?=null
)
如果我尝试登录,它工作正常,但一直如此
response.body()?.response?.message
return 空
我该如何解决?
编辑 1
不能为空,因为我不是在获取数据,而是在传递设置的信息, 我也认为这可能是后端问题,但我已经在 Postman 上进行了测试,并且始终 return 正确的格式(实际上是我在上面发布的 JSON)
后端
class UserController extends Controller
{
function index(Request $request)
{
$rules = array(
'email' =>'required',
'password' =>'required'
);
$messages = [
'email.required'=> 'email mancante',
'password.required'=> 'password mancante'
];
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)){
$validator = Validator::make($request->all(),$rules,$messages);
if($validator->fails()){
$text_message = $validator->errors()->first();
$response = [
'response'=>[
'error' => 'true',
'message' => $text_message
]
];
return response($response,400);
}
else
{
$response = [
'response'=>[
'error' => 'true',
'message' => 'le credenziali non sono corrette'
]
];
return response($response,401);
}
}
$token = $user->createToken($request->device_name)->plainTextToken;
$APiresponse = [
'error' => 'false',
'message' => 'Accesso effettuato'
];
$response=['user'=> $user,
'token' =>$token,
'response' => $APiresponse
];
return response($response, 201);
}
改装电话
fun login(){
var email :String = txtEmailUser.text.toString()
var password :String = txtPasswordUser.text.toString()
var deviceName = android.os.Build.MODEL
mServiceV = Common.apiV
Log.d("response", deviceName)
mServiceV.login(email,password,deviceName).enqueue(object : Callback<Venditore> {
override fun onResponse(call: Call<Venditore>, response: Response<Venditore>) {
Log.d("code",response.code().toString())
Log.d("response",response.body().toString())
when(response.code()) {
400->{
Toast.makeText(
this@MainActivity,
response.body()?.response?.message,
Toast.LENGTH_SHORT
).show()
return
}
401 -> {
Toast.makeText(
this@MainActivity,
response.body()?.response?.message,
Toast.LENGTH_SHORT
).show()
return
}
201->{
GlobalVar.Myid = response.body()?.user?.id
GlobalVar.MyT = response.body()?.token
Toast.makeText(this@MainActivity, response.body()?.response?.message, Toast.LENGTH_SHORT).show()
startActivity(Intent(this@MainActivity, MagazzinoActivity::class.java))
}
else->{
if (!response.isSuccessful) {
Toast.makeText(
this@MainActivity,
"Qualcosa è andato storto",
Toast.LENGTH_SHORT
).show()
Log.d("heades", response.code().toString())
return
}
}
}
}
override fun onFailure(call: Call<Venditore>, t: Throwable) {
Toast.makeText(this@MainActivity, t.message!!, Toast.LENGTH_SHORT).show()
}
})
}
更新
response.body()?.response?.message 在登录成功时工作,对不起,我以为不是
问题 如果是 400 或 401 代码,我的 api 响应只是
"response": {
"error": "true",
"message": "le credenziali non sono corrette"
}
可能是这个问题,我还应该 return 这种格式吗?
{
"user": {
"id": null,
"name": "null",
"lastname": "null",
"email": "null",
"email_verified_at": null,
"role_id": null,
"created_at": null,
"updated_at": null
},
"token": "null",
"response": {
"error": "false",
"message": "some message"
}
}
终于解决了!
希望这对我身边的人有所帮助。
当调用 4xx 代码时 response.body() 为空而不是 response.errorBody(), 因此所有 API 响应都将存在(如果您设置自定义 4xx 代码)或默认服务器响应。
理解后我还发现Retrofit不会像Body()那样转换errorBody()所以你应该自己转换。
解决方案
val gson = Gson()
val type = object : TypeToken<APIresponse>() {}.type
var errorResponse: APIresponse? = gson.fromJson(response.errorBody()!!.charStream(), type)
//Retriving just message
Toast.makeText(this@MainActivity, errorResponse?.message, Toast.LENGTH_SHORT).show()