質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

1回答

2056閲覧

Retrofit2とMoshiを用いてJSONオブジェクトに対応したPOJOを作成したい

negoto

総合スコア13

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2020/03/28 01:26

Retorfit2とMoshiを用いてlivedoorの天気APIを利用して、天気情報を取得したいです。以下のコードを実行したところ以下のエラーがエミュレーターに表示され、取得できません。どこを直せばよいか教えてください。
expected begin_array but was begin_object at path $

どこを直せばよいか教えてください。

以下のJSONオブジェクトを変換させようとしています。

JSON

1{ 2 "pinpointLocations": [ 3 { 4 "link": "http://weather.livedoor.com/area/forecast/2710000", 5 "name": "大阪市" 6 }, 7 { 8 "link": "http://weather.livedoor.com/area/forecast/2714000", 9 "name": "堺市" 10 }, 11 { 12 "link": "http://weather.livedoor.com/area/forecast/2720200", 13 "name": "岸和田市" 14 }, 15 { 16 "link": "http://weather.livedoor.com/area/forecast/2720300", 17 "name": "豊中市" 18 }, 19 { 20 "link": "http://weather.livedoor.com/area/forecast/2720400", 21 "name": "池田市" 22 }, 23 { 24 "link": "http://weather.livedoor.com/area/forecast/2720500", 25 "name": "吹田市" 26 }, 27 { 28 "link": "http://weather.livedoor.com/area/forecast/2720600", 29 "name": "泉大津市" 30 }, 31 { 32 "link": "http://weather.livedoor.com/area/forecast/2720700", 33 "name": "高槻市" 34 }, 35 { 36 "link": "http://weather.livedoor.com/area/forecast/2720800", 37 "name": "貝塚市" 38 }, 39 { 40 "link": "http://weather.livedoor.com/area/forecast/2720900", 41 "name": "守口市" 42 }, 43 { 44 "link": "http://weather.livedoor.com/area/forecast/2721000", 45 "name": "枚方市" 46 }, 47 { 48 "link": "http://weather.livedoor.com/area/forecast/2721100", 49 "name": "茨木市" 50 }, 51 { 52 "link": "http://weather.livedoor.com/area/forecast/2721200", 53 "name": "八尾市" 54 }, 55 { 56 "link": "http://weather.livedoor.com/area/forecast/2721300", 57 "name": "泉佐野市" 58 }, 59 { 60 "link": "http://weather.livedoor.com/area/forecast/2721400", 61 "name": "富田林市" 62 }, 63 { 64 "link": "http://weather.livedoor.com/area/forecast/2721500", 65 "name": "寝屋川市" 66 }, 67 { 68 "link": "http://weather.livedoor.com/area/forecast/2721600", 69 "name": "河内長野市" 70 }, 71 { 72 "link": "http://weather.livedoor.com/area/forecast/2721700", 73 "name": "松原市" 74 }, 75 { 76 "link": "http://weather.livedoor.com/area/forecast/2721800", 77 "name": "大東市" 78 }, 79 { 80 "link": "http://weather.livedoor.com/area/forecast/2721900", 81 "name": "和泉市" 82 }, 83 { 84 "link": "http://weather.livedoor.com/area/forecast/2722000", 85 "name": "箕面市" 86 }, 87 { 88 "link": "http://weather.livedoor.com/area/forecast/2722100", 89 "name": "柏原市" 90 }, 91 { 92 "link": "http://weather.livedoor.com/area/forecast/2722200", 93 "name": "羽曳野市" 94 }, 95 { 96 "link": "http://weather.livedoor.com/area/forecast/2722300", 97 "name": "門真市" 98 }, 99 { 100 "link": "http://weather.livedoor.com/area/forecast/2722400", 101 "name": "摂津市" 102 }, 103 { 104 "link": "http://weather.livedoor.com/area/forecast/2722500", 105 "name": "高石市" 106 }, 107 { 108 "link": "http://weather.livedoor.com/area/forecast/2722600", 109 "name": "藤井寺市" 110 }, 111 { 112 "link": "http://weather.livedoor.com/area/forecast/2722700", 113 "name": "東大阪市" 114 }, 115 { 116 "link": "http://weather.livedoor.com/area/forecast/2722800", 117 "name": "泉南市" 118 }, 119 { 120 "link": "http://weather.livedoor.com/area/forecast/2722900", 121 "name": "四條畷市" 122 }, 123 { 124 "link": "http://weather.livedoor.com/area/forecast/2723000", 125 "name": "交野市" 126 }, 127 { 128 "link": "http://weather.livedoor.com/area/forecast/2723100", 129 "name": "大阪狭山市" 130 }, 131 { 132 "link": "http://weather.livedoor.com/area/forecast/2723200", 133 "name": "阪南市" 134 }, 135 { 136 "link": "http://weather.livedoor.com/area/forecast/2730100", 137 "name": "島本町" 138 }, 139 { 140 "link": "http://weather.livedoor.com/area/forecast/2732100", 141 "name": "豊能町" 142 }, 143 { 144 "link": "http://weather.livedoor.com/area/forecast/2732200", 145 "name": "能勢町" 146 }, 147 { 148 "link": "http://weather.livedoor.com/area/forecast/2734100", 149 "name": "忠岡町" 150 }, 151 { 152 "link": "http://weather.livedoor.com/area/forecast/2736100", 153 "name": "熊取町" 154 }, 155 { 156 "link": "http://weather.livedoor.com/area/forecast/2736200", 157 "name": "田尻町" 158 }, 159 { 160 "link": "http://weather.livedoor.com/area/forecast/2736600", 161 "name": "岬町" 162 }, 163 { 164 "link": "http://weather.livedoor.com/area/forecast/2738100", 165 "name": "太子町" 166 }, 167 { 168 "link": "http://weather.livedoor.com/area/forecast/2738200", 169 "name": "河南町" 170 }, 171 { 172 "link": "http://weather.livedoor.com/area/forecast/2738300", 173 "name": "千早赤阪村" 174 } 175 ], 176 "link": "http://weather.livedoor.com/area/forecast/270000", 177 "forecasts": [ 178 { 179 "dateLabel": "今日", 180 "telop": "雨時々曇", 181 "date": "2020-03-28", 182 "temperature": { 183 "min": null, 184 "max": { 185 "celsius": "14", 186 "fahrenheit": "57.2" 187 } 188 }, 189 "image": { 190 "width": 50, 191 "url": "http://weather.livedoor.com/img/icon/17.gif", 192 "title": "雨時々曇", 193 "height": 31 194 } 195 }, 196 { 197 "dateLabel": "明日", 198 "telop": "曇時々雨", 199 "date": "2020-03-29", 200 "temperature": { 201 "min": { 202 "celsius": "8", 203 "fahrenheit": "46.4" 204 }, 205 "max": { 206 "celsius": "15", 207 "fahrenheit": "59.0" 208 } 209 }, 210 "image": { 211 "width": 50, 212 "url": "http://weather.livedoor.com/img/icon/10.gif", 213 "title": "曇時々雨", 214 "height": 31 215 } 216 } 217 ], 218 "location": { 219 "city": "大阪", 220 "area": "近畿", 221 "prefecture": "大阪府" 222 }, 223 "publicTime": "2020-03-28T05:00:00+0900", 224 "copyright": { 225 "provider": [ 226 { 227 "link": "http://tenki.jp/", 228 "name": "日本気象協会" 229 } 230 ], 231 "link": "http://weather.livedoor.com/", 232 "title": "(C) LINE Corporation", 233 "image": { 234 "width": 118, 235 "link": "http://weather.livedoor.com/", 236 "url": "http://weather.livedoor.com/img/cmn/livedoor.gif", 237 "title": "livedoor 天気情報", 238 "height": 26 239 } 240 }, 241 "title": "大阪府 大阪 の天気", 242 "description": { 243 "text": " 大阪府は、前線や湿った空気の影響で雨となっています。\n\n 28日の大阪府は、前線や湿った空気の影響で雨となり、朝から昼過ぎまでは曇るでしょう。\n\n 29日の大阪府は、前線や湿った空気の影響でおおむね曇り、明け方まで雨が降る見込みです。\n\n【近畿地方】\n 近畿地方は、前線や湿った空気の影響で曇り、雨の降っている所があります。\n\n 28日の近畿地方は、前線や湿った空気の影響で曇り、夕方から雨が降るでしょう。\n\n 29日の近畿地方は、前線や湿った空気の影響でおおむね曇り、朝まで雨が降る見込みです。", 244 "publicTime": "2020-03-28T04:47:00+0900" 245 } 246}

data class は以下のようになり、WeatherPropertyに詰めてやりとりを行うとし、それぞれのdata classは独立させてます。

Kotlin

1data class WeatherProperty( 2 val copyright: Copyright, 3 val description: Description, 4 val forecasts: Forecast, 5 val link: String, 6 val location: Location, 7 val pinpointLocations: PinpointLocation, 8 val publicTime: String, 9 val title: String 10)

Kotlin

1data class Copyright( 2 val provider: Provider, 3 val link: String, 4 val title: String, 5 val image: Image 6)

Kotlin

1data class Provider( 2 val providerlist: List<ProviderList> 3)

Kotlin

1data class ProviderList( 2 val link: String, 3 val name: String 4)

Kotlin

1data class Description( 2 val publicTime: String, 3 val text: String 4)

Kotlin

1 2data class Forecast( 3 val forecastList: List<ForecastList> 4)

Kotlin

1data class ForecastList( 2 val date: String, 3 val dateLabel: String, 4 val image: ImageX, 5 val telop: String, 6 val temperature: Temperature 7)

Kotlin

1data class ImageX( 2 val height: Int, 3 val title: String, 4 val url: String, 5 val width: Int 6)

Kotlin

1data class Temperature( 2 val max: Max, 3 val min: Any 4)

Kotlin

1data class Location( 2 val area: String, 3 val city: String, 4 val prefecture: String 5)

Kotlin

1data class PinpointLocation( 2 val linkName: List<LinkName> 3)

Kotlin

1data class LinkName( 2 val link: String, 3 val name: String 4)

取得してきたJSONオブジェクトを変換するAPIは以下のようにしています。

Kotlin

1private const val BASE_URL = "http://weather.livedoor.com/forecast/webservice/json/" 2 3 4private val moshi = Moshi.Builder() 5 .add(KotlinJsonAdapterFactory()) 6 .build() 7 8//retrofitオブジェクトをMoshi使ってMoshiオブジェクトに変換 9private val retrofit = Retrofit.Builder() 10 .addConverterFactory(MoshiConverterFactory.create(moshi)) 11 .addCallAdapterFactory(CoroutineCallAdapterFactory()) 12 .baseUrl(BASE_URL) 13 .build() 14 15interface WeatherApiService { 16 @GET("v1?city=270000") 17 fun getProperties(): 18 Deferred<List<WeatherProperty>> 19} 20 21object WeatherApi { 22 val retrofitService : WeatherApiService by lazy { 23 retrofit.create(WeatherApiService::class.java) 24 } 25}

以上よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2020/03/28 02:12

WeatherProperty の pinpointLocations と forecasts と、Copyright の provider は配列なので、List か何かにしないといけないのでは。
negoto

2020/03/28 03:14 編集

すみません、JSONの見方がまだよくわかってないのですが、 pinponitLocations、forecasts、Copyrightのproviderのそれぞれの中身が配列になっていて、pinpointoLocations、forecasts、providerは配列になっていないと思いますが認識違いでしょうか?
hoshi-takanori

2020/03/28 03:20

あ、ちゃんと見てませんでした。たぶん、質問文のクラス構造だと {  "pinpointLocations": {   "linkName": [    {     "link": "http://weather.livedoor.com/area/forecast/2710000",     "name": "大阪市"    }, という JSON になると思います。つまり、PinpointLocation, Forecast, Provider というクラスは不要だと思います。
negoto

2020/03/28 06:32

すみません、そうするとどういうdata classになるか教えてもらえますか? まだよくわかりません。
guest

回答1

0

ベストアンサー

PinpointLocation, Forecast, Provider は削除して、以下の修正で動くと思います。

Kotlin

1data class WeatherProperty( 2 val copyright: Copyright, 3 val description: Description, 4 val forecasts: List<ForecastList>, // List に変更 5 val link: String, 6 val location: Location, 7 val pinpointLocations: List<LinkName>, // List に変更 8 val publicTime: String, 9 val title: String 10)

Kotlin

1data class Copyright( 2 val provider: List<ProviderList>, // List に変更 3 val link: String, 4 val title: String, 5 val image: ImageX // クラス名修正 6)

Kotlin

1data class Temperature( 2 val max: Max, 3 val min: Any? // null があるので ? を追加 (Max? でもいいような) 4)

Kotlin

1interface WeatherApiService { 2 @GET("v1?city=270000") 3 fun getProperties(): 4 Deferred<WeatherProperty> // たぶんこれは List じゃないはず 5}

あと、開発やデバッグのコツですが、JSON パーザーは余分なものは無視するので、いきなり全部のデータを定義するのではなく、まず次のような最低限のデータを定義して、少しずつ追加していけばいいと思います。

Kotlin

1data class WeatherProperty ( 2 val description: Description, 3 val title: String 4)

投稿2020/03/28 07:18

編集2020/03/28 07:19
hoshi-takanori

総合スコア7901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

negoto

2020/03/28 08:22

やっぱりできませんでした。。。 アドバイスしてくれたように最低限のでやってみてもダメでした。 基本的なJSONで練習してみます。 回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問