문근
176
2021-07-16 13:17:34
4
225

android retrofit2 질문드립니다



레트로핏 클래스 

private val retrofit: Retrofit = Retrofit.Builder()
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl(serverIp)
        .build()

    
    val userApi: UserAPI = retrofit.create(UserAPI::class.java)

data 리퀘스트 클래스

data class LoginRequest(
    @SerializedName("userId") val userId: String?,
    @SerializedName("userName") val userName: String?,
    @SerializedName("password") val password: String?,
    @SerializedName("phone") val phone: String?,
    @SerializedName("gender") val gender: String?,
    @SerializedName("age") val age: Int?,
    @SerializedName("email") val email: String?,
    @SerializedName("provider") val provider: String?,
    @SerializedName("pushNotiFl") val pushNotiFl: String?,
    @SerializedName("kakaoNotiFl") val kakaoNotiFl: String?,
    @SerializedName("deviceToken") val deviceToken: String?
)

유저 api

@POST("user")
    fun loginBody(
        @Body loginRequest : LoginRequest
    ) : Single<UserResponse>

유저 모델

fun loginBody(body: LoginRequest): Single<UserResponse>

유저 impl

override fun loginBody(body: LoginRequest): Single<UserResponse> {
        return RetrofitAPI.getInstance().userApi.loginBody(body)
    }

콜하는 뷰모델

fun loginEvent(userId: String?, userName: String?, password: String?, phone: String?, gender: String?, age: Int?,
                   email: String?, provider: String?, pushNotiFl:String?, kakaoNotiFl: String?, deviceToken: String?) {

        val test: LoginRequest = LoginRequest(userId, userName, password, phone, gender, age, email, provider, pushNotiFl, kakaoNotiFl, deviceToken)
        Timber.d("Test Checked ! $test")

        addDisposable(
            model.loginBody(test)
                .subscribeOn(Schedulers.io())
                .subscribe({
                    _loginResult.postValue(it)
                }, {
                    Timber.d("response error, message : ${it.localizedMessage}")
                })
        )

    }

리스폰스 확인하는 액티비티

viewModel.loginResult.observe(this@LoginActivity, Observer {
                if (it.status == 200){
                    Timber.d("Test Checked)
                }else{
                    Timber.d("Test Checked error ${it.status} ${it.responseData.login.userId}")
                }
            })

okhttp log



포스트맨 결과



포스트맨이 정상인거 보면 서버쪽 에러는 아니고 

activity 에서 response status가 0가 나오고있습니다 

end point 에러라면 rxjava 사용한 viewmodel 에서 response error 이 나와야 정상이라고 생각합니다

하지만 액티비티에서 response status 가 나온다는건 서버에 정상적으로 api를 찌르는 데는 성공했으니 response 가 나온다고 생각합니다 


그럼 여기서 response status가 0이 뜨고 다른 response data가 null 이뜨는 이유는 추측이지만 okhttp 로그를 확인해보니 json이 순서대로 만들어지지 않고 이상하게 조합이 되는 것 이라고 생각됩니다

여기서 json이 순서대로 조합되지 않는 이유도 잘모르겠습니다 리퀘스트 데이터에 시리얼라이즈 데이터도 재대로 맵핑해줬다고 생각되는데 이부분부터 고쳐나가야 다음 추측을 해보면서 풀어갈텐데 이부분이 이해가 안되서 혹시 아시는분 있으신가요? 아니면 솔루션을 제안해주셔도 감사할거같습니다 





0
  • 답변 4

  • CyanGlint
    1k
    2021-07-16 16:25:30

    UserResponse 클레스가 API 반환값과 일치하게 구성됐는지 확인 해 보세요

    it.status 이게 API응답의 일부를 받아서 UserResponse에 매핑해주는 값인 것 같은데

    it.status == 200을 체크한다는건 사용자 정의 state가 아닌 http statusCode 인거같고 

    http statusCode에 0은 없으니 int 기본값일테고

    기본값이 들어있다는건 매핑이 제대로 안됐다는겁니다.


    Retrofit2 build할 때 로거를 붙여보시는 것도 추천 드려요 구글링해보면 나올겁니다.

    로그캣에 Request URI랑 Response Status Code가 정확하게 찍히는 수준까지만 로깅해도

    판단하는데 많은 도움이 됩니다.

  • 문근
    176
    2021-07-16 18:21:02

     

    CyanGlint // logger 를 써서 올렷는데 여긴 안올라갔네요 ㅠㅠ 

    https://stackoverflow.com/questions/68356733/android-retrofit2-response-data-null-how-to-fix-it

    스택오버플로에도 올렸는데 추측으론 매핑이 잘 안된거같은데 여기서 json이 왜 이렇게 만들어진건지도 모르겠습니다 코드보면 이상할게없는거같은데 
  • CyanGlint
    1k
    2021-07-19 14:49:40

    Request 말고 Response를 확인 해 보세요

    로거에 200OK 떨어졌는데 응답값이 제대로 안 찍히는건

    data class UserResponse가 응답 json 양식에 안 맞는 것으로 보입니다.

  • 문근
    176
    2021-07-22 14:53:12

    CyanGlint //


    감사합니다 답글 보시면 알겠지만 저도 그렇게 확인했습니다 

    관심 주신 덕분에 해결하는데 도움이 되었습니다 정말 감사합니다

  • 로그인을 하시면 답변을 등록할 수 있습니다.