web-dev-qa-db-ja.com

Retrofit 2.0が「IllegalArgumentException:@Fieldパラメーターはフォームエンコーディングでのみ使用できます」をスローします。正しいAPIクエリを実行して修正する方法

私の問題は、受信したAPIでRetrofit 2.0を使用する方法がわからないということです-以下で説明します...

まず、ユーザー名、パスワード、fbID(オプション)、gmailID(オプション)、twitID(オプション)、性別、誕生日、場所(必須ではありません-longとlatに値がある場合)、経度(オプション)、緯度(オプション) 、profileImage(オプション)。

すべてのパラメーターが正常な場合-_status = true_を受け取ります。そうでない場合-_status = false_および間違った必須パラメーターを受信します(たとえば、メールは既に取得されています)

したがって、_status = true_または_status = false_と最大5つのパラメーター(ユーザー名、メール、パスワード、性別、誕生日)の配列を受け取ることができます。

私はこれを試しました_API Interface_:

_public interface AuthRegisterUserApi {
    @PUT()
    Call<AuthRegisterUserModel> getStatus(
            @Field("username") String username,
            @Field("email") String email,
            @Field("password") String password,
            @Field("fbID") String fbID,
            @Field("gmailID") String gmailID,
            @Field("twitID") String twitID,
            @Field("gender") String gender,
            @Field("birthDate") String birthDate,
            @Field("location") String location,
            @Field("longitude") String longitude,
            @Field("latitude") String latitude,
            @Field("profileImage") String profileImage
            );

    class Factory {
        private static AuthRegisterUserApi service;

        public static AuthRegisterUserApi getInstance() {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(ApiConstants.REGISTER_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            service = retrofit.create(AuthRegisterUserApi.class);

            return service;
        }
    }
}
_

このAPIモデル(Pastebin.com)を使用

Activityのこのコード:

_AuthRegisterUserApi.Factory.getInstance()
        .getStatus(
                usernameEditText.getText().toString(),
                emailEditText.getText().toString(),
                passwordEditText.getText().toString(),
                "", "", "",
                (maleRadioButton.isChecked() ? "male" : "female"),
                mYear + "-" + mMonth+1 + "-" + mDay,
                (geoLocationToggleButton.isChecked() ? geoLocationEditText.getText().toString() : ""),
                (!geoLocationToggleButton.isChecked() ? "50" : ""),
                (!geoLocationToggleButton.isChecked() ? "50" : ""),
                "")
        .enqueue(new Callback<AuthRegisterUserModel>() {
    @Override
    public void onResponse(Call<AuthRegisterUserModel> call, Response<AuthRegisterUserModel> response) {
        if(response.isSuccessful()) {
            if (response.body().isStatus()) {
                showToast(getApplicationContext(), "Registration ok.");
            } else {
                response.body().getInfo().getUsername();
            }
        }
    }

    @Override
    public void onFailure(Call<AuthRegisterUserModel> call, Throwable t) {

    }
});
_

エラーが発生しました:Java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1) for method AuthRegisterUserApi.getStatus

Postmanを使用してユーザーを登録しようとしましたが、オプションBody-> _x-www-form-urlencoded_を使用すると機能します。

このAPIへのregisterクエリを作成するにはどうすればよいですか?_@Field_を別のものに変更しますか?私はいつもこのエラーを持っています...

編集:_API Interface_をこれに変更する必要があります

_public interface AuthRegisterUserApi {
    @FormUrlEncoded
    @PUT("/api/register")
    Call<AuthRegisterUserModel> getStatus(
            @Field("username") String username,
            @Field("email") String email,
            @Field("password") String password,
            @Field("fbID") String fbID,
            @Field("gmailID") String gmailID,
            @Field("twitID") String twitID,
            @Field("gender") String gender,
            @Field("birthDate") String birthDate,
            @Field("location") String location,
            @Field("longitude") String longitude,
            @Field("latitude") String latitude,
            @Field("profileImage") String profileImage
            );

    class Factory {
        private static AuthRegisterUserApi service;

        public static AuthRegisterUserApi getInstance() {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(ApiConstants.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

            service = retrofit.create(AuthRegisterUserApi.class);

            return service;
        }
    }
}
_

_BASE_URL = http://ip_address:8400_私のために...

しかし、まだエラーが発生しました:_Response.rawResponse = Response{protocol=http/1.1, code=400, message=Bad Request, url=http://ip_address:8400/api/register}_。同じデータでPostmanを使用して、code = 201 Createdを受け取りました。 理由がわからない...

32
y07k2

問題は、PUTをしようとするためです。 longitude\latitude\location値なし-空のString

つまり、API側に問題がありました。それを避けるために、メソッドをこれに変更しました:

@FormUrlEncoded
@PUT(ApiConstants.REGISTER_URL_PART)
Call<RegisterModel> registerUser(
        @Field("username") String username,
        @Field("email") String email,
        @Field("password") String password,
        @Field("fbID") String fbID,
        @Field("gmailID") String gmailID,
        @Field("twitID") String twitID,
        @Field("gender") String gender,
        @Field("birthDate") String birthDate,
        @Nullable @Field("location") String location,
        @Nullable @Field("longitude") String longitude,
        @Nullable @Field("latitude") String latitude,
        @Field("profileImage") String profileImage
);

さて、そのうちの1つに値を指定しない場合、このフィールドを単純に囲みません。

7
y07k2

あなたのリクエストは正しくエンコードされていませんが、郵便配達員ですので、変更してください:

@FormUrlEncoded
@PUT("/api/register")
    Call<AuthRegisterUserModel> getStatus(
            @Field("username") String username,
            @Field("email") String email,
            @Field("password") String password,
            @Field("fbID") String fbID,
            @Field("gmailID") String gmailID,
            @Field("twitID") String twitID,
            @Field("gender") String gender,
            @Field("birthDate") String birthDate,
            @Field("location") String location,
            @Field("longitude") String longitude,
            @Field("latitude") String latitude,
            @Field("profileImage") String profileImage);

大丈夫か教えてください。

33

restメソッド呼び出しの上で@FormUrlEncodedを見逃しただけです。

19
Rajesh.k

同様のエラーメッセージが表示され、インターフェイス定義で@ForUrlEncodedアノテーションが欠落していることに気付きました-フォームパーツを使用する残りの呼び出しの上に、最初に投稿されたコードブロックで行ったのと同じように見えます。それを見てください。

お役に立てれば。

2
Saulo Aguiar