如何使用Retrofit,Gson和RxKotlin / RxJava2解析嵌套的JSON

时间:2019-07-18 17:04:59

标签: android kotlin retrofit2 rx-java2 rx-kotlin2

我正在RtKotlin中(第一次)在Kotlin中使用Retrofit从自定义API提取数据。我正在尝试将JSON响应转换为自定义User对象。

由于JSON回复中有一些嵌套对象,因此我尝试制作自己的自定义数据类来镜像每个对象。

翻新构建器(无论如何都是相关零件):

    private val TAG : String = "TAG ${this::class.java.simpleName}"

    private var user : User? = null
    private var compositeDisposable : CompositeDisposable? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        loadData()

        button.setOnClickListener{
            Log.d(TAG, user.toString()+" "+user?.id)
        }
    }

    private fun loadData(){
        val requestInterface = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(getOkHttpClient())
            .build().create(PracticeService::class.java)

        requestInterface.listUsers("Basic ${AUTH_STRING}")
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe({ result ->
                Log.d(TAG, "Yay it worked ${result.toString()}")
                this.user = result
            }, { error ->
                error.printStackTrace()
            })
    }

API服务接口:

interface PracticeService {
    @GET("auth/user")
        fun listUsers(@Header("Authorization") authHeader : String) : Observable<MainActivity.User>
}

我的自定义用户数据类:

data class User(
    @SerializedName("id")
    var id : Int,
    @SerializedName("email")
    var email : String,
    @SerializedName("username")
    var username : String,
    /*@SerializedName ("")
    var password : String?,*/
    @SerializedName("firstName")
    var firstName : String,
    @SerializedName("lastName")
    var lastName : String?,
    @SerializedName("onboardingStep")
    var onboardingStep : String?,
    @SerializedName("notificationPrefs")
    var notificationPrefs: NotificationPrefs?,
    @SerializedName("birthdate")
    var birthdate : String?,
    @SerializedName("height")
    var height : Measurement?,
    @SerializedName("weight")
    var weight: Measurement?,
    @SerializedName("gender")
    var gender : String?,
    @SerializedName("mealsPerDay")
    var mealsPerDay : Int?,
    @SerializedName("workoutIntensity")
    var workoutIntensity : Int?,
    @SerializedName("exerciseDaysPerWeek")
    var exerciseDaysPerWeek : Int?,
    @SerializedName("largeBreakfastCalorieSurplus")
    var largeBreakfastCalorieSurplus : Boolean?,
    @SerializedName("snacksPercentTotalFood")
    var snacksPercentTotalFood : Double?,
    @SerializedName("cafePrefs")
    var cafePrefs: CafePrefs?,
    @SerializedName("dietaryRestrictions")
    var dietaryRestrictions : Array<String>?,
    @SerializedName("weekdayPctBreakfast")
    var weekdayPercentBreakfast : Double?,
    @SerializedName("weekdayPercentLunch")
    var weekdayPercentLunch : Double?,
    @SerializedName("weekdayPercentDinner")
    var weekdayPercentDinner : Double?,
    @SerializedName("weekendPercentLunch")
    var weekendPercentLunch : Double?,
    @SerializedName("weekendPercentDinner")
    var weekendPercentDinner : Double?,
    @SerializedName("goals")
    var goals : Array<Goal>?,
    @SerializedName("favorites")
    var favorites : Array<Favorite>?,
    @SerializedName("customFoodItems")
    var customFoodItems : Array<CustomFoodItem>
)

//Nested Data Classes for User Class
data class NotificationPrefs(
    @SerializedName("enabled")
    var enabled : Boolean?,
    @SerializedName("healthyEatingTips")
    var healthyEatingTips : Boolean?,
    @SerializedName("targetReminders")
    var targetReminders : Boolean?,
    @SerializedName("newRewards")
    var newRewards : Boolean?
)
data class Goal(
    @SerializedName("id")
    var id : String,
    @SerializedName("timeline")
    var timeline : Timeline?,
    @SerializedName("weightGoal")
    var weightGoal : WeightGoal?,
    @SerializedName("customGoals")
    var customGoals : Array<BasicGoal>?
)
data class CustomFoodItem( var customFoodItemProperty1 : String?)
data class Favorite( var favProperty1 : String?)
data class Timeline(
    @SerializedName("weeks")
    var weeks : Int?,
    @SerializedName("date")
    var date : String?
)
data class WeightGoal( var weightGoalType : String?, var measurement : Measurement?)
data class Measurement(
    @SerializedName("value")
    var value : Double?,
    @SerializedName("unit")
    var unit : String?
)
data class BasicGoal(
    @SerializedName("nutrient")
    var nutrient : String?,
    @SerializedName("gramsPerDay")
    var gramsPerDay : Int?,
    @SerializedName("percentMacros")
    var percentMacros : Double?
)
data class CafePrefs(
    @SerializedName("breakfast")
    var breakfast : String?,
    @SerializedName("lunch")
    var lunch : String?,
    @SerializedName("dinner")
    var dinner : String?
)

以及示例JSON API响应:

// The API is currently not working so I'll put this in when I can

该应用程序能够从API提取JSON(登录后我可以看到结果,并与Postman进行交叉验证表明它们确实正确),但是在Retrofit实例中通过集成的GSON转换器解析JSON之后,返回了用户对象的每个值均为0或null。我该如何处理?有没有需要完全定制的GSON序列化器和解串器的方法?

0 个答案:

没有答案