21553


初めて質問させていただきます。情報の不足がありましたら追加させていただきます。

AndroidでString型の変数(userID)を持つオブジェクト(UserEntity)をJSONデータに変換してPOSTしたいのですが、以下のエラーが出て困っています。

logcat  
`E/HomeActivity: エラー :com.google.gson.JsonSyntaxException:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line
1 column 2 path $`

通信処理の際にRxAndroidを用いています。

HomeActivity.java

[code]

    public class HomeActivity extends AppCompatActivity {
    
    //  通信用の定数など
    public static final String BASE_URL = "http://example.com/index.php";
    private static final String TAG = HomeActivity.class.getSimpleName();
    private Subscription subscription;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
    
        //  Gson
        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .registerTypeAdapter(Date.class, new DateTypeAdapter())
                .create();
    
        //  Retrofit
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    
        //  API
        UserApi uApi = retrofit.create(UserApi.class);
    
        //  UserEntity
        UserEntity userInstance = new UserEntity(userID);
    
    
        //  非同期処理
        this.subscription = uApi.createUser(userInstance)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<UserEntity>() {
                    @Override
                    public void onNext(UserEntity ue) {
                        Log.d(TAG, "onNext()にきた");
                    }
    
                    @Override
                    public void onCompleted() {
                        Log.d(TAG, "onComplete()にきた");
                    }
    
                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "エラー : " + e.toString());
                    }
                });
    }
    
    @Override
    protected void onDestroy() {
        //  サブスクライブ解除
        this.subscription.unsubscribe();
        super.onDestroy();
    }
    
[/code]

}

UserApi.java

[code]

    public interface UserApi {
    @POST("userfirst/write.json")
    public Observable<UserEntity> createUser(@Body UserEntity ue);
    
[/code]

}

UserEntity.java

[code]

    public class UserEntity {
    
    //  コンストラクタ
    public UserEntity(String userID){
        this.userID = userID;
    }
    
    //  JSONとの対応
    @Expose
    @SerializedName("user_id")
    private String userID;
    
[/code]

}

app/build.gradle

[code]

    dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.google.code.gson:gson:2.4'
    compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
    compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
    compile 'com.squareup.okhttp:okhttp:2.7.0'
    compile 'io.reactivex:rxandroid:0.24.0'
    compile 'io.reactivex:rxjava:1.1.0'
    compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
    compile 'io.reactivex:rxandroid:1.1.0'
    
[/code]

}

エラーメッセージで調べてみたものの、解決方法を探し出すことができませんでした。  
どなたかわかる方がいらっしゃいましたらよろしくお願いいたします。


CC BY-SA 3.0
2016-01-30T09:10:59.593
21505
2016-02-01T02:08:28.750
2016-01-30T10:18:02.010
14183
14183
question
android java retrofit
Retrofit、Gson、RxAndroidを使ったPOST通信でgson.JsonSyntaxExceptionが出る


自己解決しました。  
レスポンスとして返ってくるものの型の指定が誤っていたようです。

サーバー側からはStringがレスポンスとして返ってくるので

[code]

    @POST("userfirst/write.json")
    public Observable<String> createUser(@Body UserEntity ue);
    
[/code]

とすべきだったようです。

ちなみにエラー文についていろいろ調べたのでついでに載せておきます。

BEGIN_ARRAYでいうARRAYとは、

[code]

    [ {    }, {    }, ... ]
    
[/code]

という形であることを求められるようです。

BEGIN_OBJECTのOBJECTとは自分の定義したクラスなどのObjectのことで、各フィールドとそれに対応するArrayを持っているので

[code]

    { "   " : [    ],
    　"   " : [    ], ... }
    
[/code]

という形のJSONになっていないといけないようです。

送る前のデータをtoJSON()でJSONにしてログに出力してみてわかりました。


CC BY-SA 3.0
2016-02-01T02:08:28.750
21553
2016-02-01T02:08:28.750
14183
21505
answer