Android中Retrofit请求API返回实体类属性为空问题排查
Retrofit请求返回200但LoginResponse属性全为null的排查与解决
以下是针对该问题的核心排查点和解决方案:
1. 确认实际响应的JSON结构
首先必须验证API返回的真实JSON内容是否与预期一致——服务器可能返回200状态码,但响应体结构和你定义的LoginResponse不匹配,这是导致属性为空的常见原因。
解决方法:添加OkHttp日志拦截器,打印完整的请求和响应内容:
class RetrofitConfig { companion object { var URL_API = "I cant share the api link" fun getRetrofit(): Retrofit { // 添加日志拦截器,打印完整请求响应 val loggingInterceptor = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } val okHttpClient = OkHttpClient.Builder() .addInterceptor(loggingInterceptor) .build() return Retrofit.Builder() .baseUrl(URL_API) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build() } } }
运行后查看Logcat中的响应体JSON:
- 如果响应是嵌套结构(比如
{"data": {...}}),需要为LoginResponse添加一层包装类:
同时修改API接口的返回类型:data class LoginResponseWrapper( @SerializedName("data") val loginData: LoginResponse )suspend fun getLoginByUserandPass( @Query("idUser") userId: String, @Query("clave") userPass: String ): Response<LoginResponseWrapper> - 如果JSON字段的名称、大小写和
@SerializedName不匹配,直接修正@SerializedName的取值即可。
2. 修正数据类的属性定义
当前LoginResponse的属性均为非空类型,但如果服务器返回的字段缺失或为null,Gson无法为非空属性赋值,会导致字符串类型属性为null、布尔类型属性默认设为false。
修改数据类为可空属性并添加默认值:
data class LoginResponse ( @SerializedName("id") var id: String? = null, @SerializedName("nombre") var uname: String? = null, @SerializedName("apellido") var ulastname: String? = null, @SerializedName("acceso") var uaccess: Boolean = false, @SerializedName("admin") var uadmin: Boolean = false )
这样即使字段未匹配到,也能明确区分是解析问题还是实例化错误。
3. 检查BaseUrl与接口路径的拼接
如果BaseUrl结尾没有/,但接口的@GET路径以/开头,会导致路径拼接错误,请求到错误的地址。比如BaseUrl是https://xxx.com/api,@GET("/RS_Usuarios")会拼成https://xxx.com/RS_Usuarios,而非预期的https://xxx.com/api/RS_Usuarios,此时服务器可能返回空结构的200响应。
统一路径拼接规则:
- 要么BaseUrl以
/结尾,比如URL_API = "https://xxx.com/api/" - 要么接口路径去掉开头的
/,比如@GET("RS_Usuarios")
4. 调整Gson解析配置
默认Gson对JSON格式要求严格,比如存在未知字段时会解析失败,或者微小的格式错误会导致无法映射。
自定义宽松的Gson实例:
val gson = GsonBuilder() .setLenient() // 允许宽松的JSON格式,避免轻微格式问题导致解析失败 .ignoreUnknownFields() // 忽略未知字段,避免服务器新增字段导致解析失败 .create() // 在Retrofit中使用该实例 .addConverterFactory(GsonConverterFactory.create(gson))
内容的提问来源于stack exchange,提问作者Daniel Florez
相关产品推荐
相关产品推荐

