>source

백엔드는 매번 동일한 키에 대해 서로 다른 값을 포함 할 수있는 json 응답을 보냅니다.

첫 번째 변형의 예

{
  "title": "2",
  "profile_image": {
    "profile_image_id": "4581542",
    "sized": "media/up/2020/48/460e689e286ca46b1006b62269ee21a22b6bdabf2496506e34e5d07c5d42c20f_user_photo_160674563705555.sized.JPG",
    "sized_w": "556",
    "sized_h": "555",
    "thumb": "media/up/2020/48/460e689e286ca46b1006b62269ee21a22b6bdabf2496506e34e5d07c5d42c20f_user_photo_160674563705555.thumb.JPG",
    "thumb_w": "90",
    "thumb_h": "90"
  },
  "profile": {
    "title": "2",
    "first_name": "John",
    "last_name": "Doe",
    "user_online_status": false
  }
}

그리고 아래는 동일한 응답의 또 다른 변형입니다. 주목 profile_image 필드는 이제 배열 유형이며 user_online_status 문자열 또는 부울 일 수도 있습니다. 또한 profile_image가 비어 있으면 항상 빈 배열입니다. 다른 경우에는 객체입니다.

{
  "title": "2",
  "profile_image": [],
  "profile": {
    "title": "2",
    "first_name": "John",
    "last_name": "Doe",
    "user_online_status": "0"
  }
}

추가 모델 클래스를 생성하지 않고 Retrofit 및 Moshi를 사용하여 이러한 응답을 구문 분석하려면 어떻게해야합니까? 맞춤형 어댑터를 사용할 수 있습니까? 예를 들어 주시겠습니까?

  • 답변 # 1

    역 직렬화 할 사용자 지정 어댑터를 만들어야합니다. ProfileImage 속성을 수동으로. Moshi가 도달하면 어댑터가 호출됩니다. profile_image 특성. 고려해야 할 두 가지 경우 :

    빈 케이스 [] API가 json 배열을 반환했을 때입니다. 이것은 당신이 받게 될 경우입니다 BEGIN_ARRAY 토큰.

    원하는 경우, 각각을 역 직렬화해야하는 ProfileImage 속성, 하나씩. 이것은 당신이받을 때 BEGIN_OBJECT 토큰

    빈 케이스가 항상 먼저 확인되도록 케이스의 순서를 유지해야합니다.

    여기에서 토큰에 대해 읽어보십시오.

    class SkipEmptyProfileAdapter: JsonAdapter<ProfileImage>() {
        override fun fromJson(reader: JsonReader): ProfileImage? = when (reader.peek()) {
            JsonReader.Token.BEGIN_ARRAY -> {
               //this the case when [] is returned. Return null 
                null
            }
           
            JsonReader.Token.BEGIN_OBJECT -> {
               // here you parse the `profile_image` property 
               // here you start iterating properties from the json object until END_OBJECT is
              // found. By the time END_OBJECT is reached you should have populated the 
              // ProfileImage object 
            }
           
            else ->  null
        }
        override fun toJson(writer: JsonWriter, value: ProfileImage?) {
            writer.value(value ?: "[]")
        }
    }
    
    

  • 답변 # 2

    백엔드 팀은 결국 해고되지 않았고 저는 오늘의 영웅이되었습니다.

    불일치에 대한 내 솔루션 profile_image 들:

    다음 유형에 대해 일관성없는 클래스 속성 표시 Any? 내 데이터 클래스

    커스텀 moshi 어댑터 구현

    사용 Map 일치하지 않는 json 필드를 구문 분석합니다.

    <시간 />

    class SkipEmptyProfileAdapter {
        @FromJson
        fun fromJson(response: UserProfileDataResponse): UserProfileDataResponse {
            if (response.profileImage is Map<*, *>) {
                val map = response.profileImage as Map<String, String>
                response.imageUrlParsed = map["sized"]
            }
            return response
        }
    }
    
    

    Moshi 빌더에 어댑터 포함

    fun provideMoshi(): Moshi {
        return Moshi.Builder()
            .add(SkipEmptyProfileAdapter()) //the ordering matters
            .add(KotlinJsonAdapterFactory())
            .build()
    }
    
    

관련 자료

  • 이전 mysql - AND 조건이있는 다른 테이블에있는 경우 선택
  • 다음 ios - Firestore에 정확한 숫자를 저장하는 방법