Java Retrofit 2.0 抛出“IllegalArgumentException:@Field 参数只能与表单编码一起使用”。如何进行正确的 API 查询并修复它?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37994301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:54:02  来源:igfitidea点击:

Retrofit 2.0 throwing "IllegalArgumentException: @Field parameters can only be used with form encoding". How to do right API query and fix it?

javaandroidapiretrofitretrofit2

提问by y07k2

My problem is that I don't know how to start using Retrofit 2.0 with received API- mentioned below...

我的问题是我不知道如何开始使用带有接收到的 API 的 Retrofit 2.0- 下面提到...

Firstly, I need to username, password, fbID (optional), gmailID (optional), twitID (optional), gender, birthDate, location (not required - if long and lat has values), longitude (optional), latitude (optional), profileImage (optional).

首先,我需要用户名、密码、fbID(可选)、gmailID(可选)、twitID(可选)、性别、出生日期、位置(不需要 - 如果 long 和 lat 有值)、经度(可选)、纬度(可选) , profileImage(可选)。

When all parameters are good - receive status = true. If not - receive status = falseand required parameters which are wrong (e.g. mail is already taken)

当所有参数都正常时接收status = true。如果不是 - 接收status = false和必需的参数是错误的(例如邮件已经被占用)

So I can receive status = trueor status = falseand array with max 5 parameters (username, email, password, gender, birthDate).

所以我可以接收 最多 5 个参数(用户名、电子邮件、密码、性别、出生日期)的status = trueor status = false和数组。

I tried this API Interface:

我试过这个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;
        }
    }
}

with this API models (Pastebin.com)

使用此 API 模型 (Pastebin.com)

and this code in Activity:

和这段代码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) {

    }
});

I have error: java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1) for method AuthRegisterUserApi.getStatus

我有错误: java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1) for method AuthRegisterUserApi.getStatus

I tried to register user using Postman and it works when I used option Body-> x-www-form-urlencoded.

我尝试使用 Postman 注册用户,当我使用 option Body->时它可以工作x-www-form-urlencoded

How can I create I registerquery to this API?Change @Fieldto something else? I have got this error always...

如何创建register对此 API 的查询?@Field别的?我总是有这个错误...

EDIT: Need to change API Interfaceto this:

编辑:需要更改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:8400for me...

BASE_URL = http://ip_address:8400为了我...

But still got error: Response.rawResponse = Response{protocol=http/1.1, code=400, message=Bad Request, url=http://ip_address:8400/api/register}. Using Postman with the same data I received code=201 Created. Don't know why...

但仍然有错误:Response.rawResponse = Response{protocol=http/1.1, code=400, message=Bad Request, url=http://ip_address:8400/api/register}. 使用 Postman 和我收到的相同数据 code=201 Created。不知道为什么...

采纳答案by y07k2

The problem was because I try to PUTe.g. longitude\ latitude\ locationwith no value - empty String.

问题是,因为我尝试PUTlongitude\ latitude\location没有价值-空String

I mean - there was a problem on API side. So to avoid that I changed method to this:

我的意思是 - 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
);

Now, when I go no value for one of them, I simply don't enclose this field.

现在,当我对其中一个没有任何价值时,我只是不附上这个字段。

回答by Raphael Teyssandier

Your request is not encoded right, but are postman, so do change that :

您的请求编码不正确,而是邮递员,因此请更改:

@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);

Tell me if it's ok.

告诉我是否可以。

回答by Saulo Aguiar

I got a similar error message and I noticed that in my interface definition I missed the @ForUrlEncoded annotation - on top of the rest call that will use the form part, which seems to be the same thing you did at the first posted code block. Take a look at it.

我收到了一个类似的错误消息,我注意到在我的接口定义中我错过了 @ForUrlEncoded 注释 - 在将使用表单部分的其余调用之上,这似乎与您在第一个发布的代码块中所做的相同。看一看。

Hope this helps.

希望这可以帮助。

回答by Rajesh.k

you just missed @FormUrlEncodedabove your Rest method call.

你刚刚错过了@FormUrlEncoded上面的 Rest 方法调用。