IT/Android

[Android] Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $ 에러

토마토조아 2019. 8. 9. 09:41
728x90

이 에러는 아래의 글과 거의 비슷한 에러이다. 에러 처리 또한 비슷한데, 에러 메시지가 아주 약간 달라서 따로 포스팅한다.

 

[Android] jsonSyntaxException Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 에러 해결, Json 파싱 처리

JSON 형식의 데이터를 다루다보면 위의 에러를 간혹 접할 수 있다. 위의 에러의 원인은 GSON으로 JSON데이터를 파싱할 때 형식이 맞지 않아서 발생하는 에러이다. 문제의 원인을 살펴보자. 일반적인 JSON의 데이터..

like-tomato.tistory.com

 

결론부터 얘기하면 이 에러의 문제도 Json을 파싱할 때 형식을 제대로 맞추지 못해서 발생하는 문제이다.

위 링크의 글의 해결방법은 Json 형식을 Json[] 배열로 받음으로써 해결을 했는데, 이번에는 다른 방법을 사용해서 해결을 해보자.

아래의 코드를 보면 되겠다. 요즘은 Kotlin + RxJava2 + Retrofit2 + OkHttp3 를 이용해서 네트워크 관련 기능을 만들고 있다.

// 레트로핏 인터페이스 부분을 변경해야 한다.

// 수정전
interface KotlinRetrofitInterface {
    @GET("repos/{owner}/{repo}/contributors")
    fun requestContributors(
        @Path("owner") owner:String,
        @Path("repo") repo:String
    ) : Single<Contributors>
}

// 방법1 : Return 부분을 ArrayList 로 형식을 변경했다.
interface KotlinRetrofitInterface {
    @GET("repos/{owner}/{repo}/contributors")
    fun requestContributors(
        @Path("owner") owner:String,
        @Path("repo") repo:String
    ) : Single<ArrayList<Contributors>>
}

// 방법2 : Return 부분을 Contributors Array 로 형식을 변경했다.
interface KotlinRetrofitInterface {
    @GET("repos/{owner}/{repo}/contributors")
    fun requestContributors(
        @Path("owner") owner:String,
        @Path("repo") repo:String
    ) : Single<Array<Contributors>>
}

위와 같이 수정하면 Rx 부분도 수정을 해줘야 한다.

// 방법1 에 대한 Rx 수정 코드
val adapter = KotlinOKHttpRetrofitRxJavaManager.getInstance()
        adapter.requestContributors("ldhcjs", "GetPackagesName")
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .doOnError {
                Toast.makeText(this, "doOnError", Toast.LENGTH_SHORT).show()
                Log.d(TAG, "doOnError")
            }
            .unsubscribeOn(Schedulers.io())
            .onErrorReturn { t: Throwable ->
                Log.d(TAG, "onErrorReturn : " + t.message)
                ArrayList()
            }
            .subscribe { result ->
                if ("User" == result[0].getType()) {
                    Toast.makeText(this, "Good", Toast.LENGTH_SHORT).show()
                    Log.d(TAG, "subscribe good")
                } else {
                    Log.d(TAG, "subscribe bad")
                }
            }


// 방법2 에 대한 Rx 수정 코드
val adapter = KotlinOKHttpRetrofitRxJavaManager.getInstance()
        adapter.requestContributors("ldhcjs", "GetPackagesName")
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .doOnError {
                Toast.makeText(this, "doOnError", Toast.LENGTH_SHORT).show()
                Log.d(TAG, "doOnError")
            }
            .unsubscribeOn(Schedulers.io())
            .onErrorReturn { t: Throwable ->
                Log.d(TAG, "onErrorReturn : " + t.message)
                arrayOf(Contributors())
            }
            .subscribe { result ->
                if ("User" == result[0].getType()) {
                    Toast.makeText(this, "Good", Toast.LENGTH_SHORT).show()
                    Log.d(TAG, "subscribe good")
                } else {
                    Log.d(TAG, "subscribe bad")
                }
            }

 

다음 포스팅은 Kotlin + RxJava2 + Retrofit2 + OkHttp3 으로 REST API와 통신하는 예제가 될 것 같다.

728x90