改造响应空,错误的数据类实现?

Posted

技术标签:

【中文标题】改造响应空,错误的数据类实现?【英文标题】:retrofit response null, wrong dataclass implementation? 【发布时间】:2021-04-26 22:22:44 【问题描述】:

我正在尝试使用此 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
    

我用于管理数据的数据类:

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

返回空值

我该如何解决?

编辑 1

它不能为空,因为我不是在获取数据而是传递设置的信息, 我也认为这可能是后端问题,但我已经在 Postman 上进行了测试,并且一直返回正确的格式(实际上是我在上面发布的 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"
    

可能是这个问题,我还是应该以这种格式返回吗?

 
    "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"     
    

【问题讨论】:

可能数据为空??您的解析似乎没问题,如果您确定数据存在,则使用查询代码更新您的问题 我必须同意@Sekiro,我真的看不出这些为空的原因,除了事实上它们实际上返回为空 已编辑,但我认为不是后端问题(我在上面解释了原因),还有其他建议吗? 【参考方案1】:

终于解决了!

希望这会对我身边的人有所帮助。

调用4xx代码时response.body()为空而不是response.errorBody(), 所以所有 APIresponse 都将在那里(如果您设置自定义 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()

【讨论】:

以上是关于改造响应空,错误的数据类实现?的主要内容,如果未能解决你的问题,请参考以下文章

正在发送多个改造电话,但有些电话从未收到响应或错误

改造 2:responseBodyConverter 转换为空对象

Retrofit2 OkHttp3 响应正文空错误

改造 POJO 空

改造 2 POST JSON 对象,响应给出错误代码 400,消息 = nul

使用不同类型的响应改造错误处理