java.lang.IllegalArgumentException:URL";https:/myurl/api/login/“我的网址”;不包含“;{username}";。(参数#1)

java.lang.IllegalArgumentException:URL";https:/myurl/api/login/“我的网址”;不包含“;{username}";。(参数#1),java,android,django-rest-framework,retrofit,retrofit2,Java,Android,Django Rest Framework,Retrofit,Retrofit2,我是android studio的新手,我正在使用java、改型和web api(django restframework)进行登录活动。我收到此错误,java.lang.IllegalArgumentException:URL“https://myurl/api/login/”不包含“{username}”。(参数#1) 对于方法UserService.login,为什么会出现此错误?即使我的web api正常工作 这是我的帖子资料 这是我的LoginActivity.java public

我是android studio的新手,我正在使用java、改型和web api(django restframework)进行登录活动。我收到此错误,java.lang.IllegalArgumentException:URL“https://myurl/api/login/”不包含“{username}”。(参数#1) 对于方法UserService.login,为什么会出现此错误?即使我的web api正常工作

这是我的帖子资料

这是我的LoginActivity.java

public class LoginActivity extends AppCompatActivity {
    EditText edtUsername;
    EditText edtPassword;
    Button btnLogin;
    UserService userService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        edtUsername = (EditText) findViewById(R.id.edtUsername);
        edtPassword = (EditText) findViewById(R.id.edtPassword);
        btnLogin = (Button) findViewById(R.id.btnLogin);
        userService = ApiUtils.getUserService();

        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String username = edtUsername.getText().toString();
                String password = edtPassword.getText().toString();
                //validate form
                if(validateLogin(username, password)){
                    //do login
                    doLogin(username, password);
                }
            }
        });

    }

    private boolean validateLogin(String username, String password){
        if(username == null || username.trim().length() == 0){
            Toast.makeText(this, "Username is required", Toast.LENGTH_SHORT).show();
            return false;
        }
        if(password == null || password.trim().length() == 0){
            Toast.makeText(this, "Password is required", Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    private void doLogin(final String username,final String password){
        Call call = userService.login(username,password);
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                if(response.isSuccessful()){
                    ResObj resObj = (ResObj) response.body();
                    if(resObj.getMessage().equals("true")){
                        //login start main activity
                        Intent intent = new Intent(LoginActivity.this, DestinationListActivity.class);
                        intent.putExtra("username", username);
                        startActivity(intent);

                    } else {
                        Toast.makeText(LoginActivity.this, "The username or password is incorrect", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(LoginActivity.this, "Error! Please try again!", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Toast.makeText(LoginActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}
我的用户服务

public interface UserService {
    @POST("https:// my url /api/login/")
    Call login(@Path("username") String username, @Path("password") String password);

}
这是我的客户

public class RetrofitClient {
    private static Retrofit retrofit = null;

    public static Retrofit getClient(String url){
        if(retrofit == null){
            retrofit = new Retrofit.Builder()
                    .baseUrl(url)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}
我的朋友

public class ResObj {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
我的小猪

public class ApiUtils {

    public static final String BASE_URL = "https:// my url /";

    public static UserService getUserService(){
        return RetrofitClient.getClient(BASE_URL).create(UserService.class);
    }
}
这是我收到的全部错误

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.smartherd.globofly, PID: 27242
    java.lang.IllegalArgumentException: URL "https:// my url /api/login/" does not contain "{username}". (parameter #1)
        for method UserService.login
        at retrofit2.Utils.methodError(Utils.java:52)
        at retrofit2.Utils.methodError(Utils.java:42)
        at retrofit2.Utils.parameterError(Utils.java:61)
        at retrofit2.RequestFactory$Builder.validatePathName(RequestFactory.java:732)
        at retrofit2.RequestFactory$Builder.parseParameterAnnotation(RequestFactory.java:375)
        at retrofit2.RequestFactory$Builder.parseParameter(RequestFactory.java:295)
        at retrofit2.RequestFactory$Builder.build(RequestFactory.java:182)
        at retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:65)
        at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:25)
        at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:168)
        at retrofit2.Retrofit$1.invoke(Retrofit.java:147)
        at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
        at $Proxy3.login(Unknown Source)
        at com.smartherd.globofly.activities.LoginActivity.doLogin(LoginActivity.java:64)
        at com.smartherd.globofly.activities.LoginActivity.access$100(LoginActivity.java:20)
        at com.smartherd.globofly.activities.LoginActivity$1.onClick(LoginActivity.java:44)
        at android.view.View.performClick(View.java:7125)
        at android.view.View.performClickInternal(View.java:7102)
        at android.view.View.access$3500(View.java:801)
        at android.view.View$PerformClick.run(View.java:27336)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
I/Process: Sending signal. PID: 27242 SIG: 9
更新 对于
@POST
类型的请求,您还可以使用
@Field
传递表单编码请求的各个字段

@FormUrlEncoded
@POST("https://www.url.com/api/login/")
Call login(@Field("username") String username, @Field("password") String password);
使用示例记录文档

要处理响应,请执行以下操作: 定义一个简单类
AuthenticationResponse

public class AuthenticationResponse {
    public String token;
}
并将其用作
登录
调用的通用类型参数:

@FormUrlEncoded
@POST("https://www.url.com/api/login/")
Call<AuthenticationResponse> login(@Field("username") String username, @Field("password") String password);

对于
@POST
类型的请求,如果需要将参数作为请求正文的一部分,则必须使用
@body
注释对这些参数进行注释。但是您只能使用一个
@Body
注释,因为用该注释声明的参数将定义请求的整个主体

@POST("https://www.url.com/api/login/")
Call login(@Body Credentials credentials);
其中,
凭证
是POJO类:

class Credentials {
    public String username;
    public String password;
}
文件

究竟为什么会发生错误? 使用
@Path(“name”)
注释时,必须在URL中为该路径参数提供占位符

而不是:

@POST("https://www.url.com/api/login/")
Call login(@Path("username") String username, @Path("password") String password);
您的调用后声明应如下所示,以便改型将知道在何处放置这些路径参数:

@POST("https://www.url.com/api/login/{username}/{password}")
Call login(@Path("username") String username, @Path("password") String password);

包含示例的文档。

您的登录http端点是否希望您将登录数据(用户名、密码)作为URL编码的参数发送到正文中? 然后尝试修改UserService界面,如下所示:

公共类资源{
私有字符串令牌;
公共字符串getToken(){
返回令牌;
}
公共void setToken(字符串令牌){
this.token=token;
}
}
公共接口用户服务{
@FormUrlEncoded
@POST(“https://myurl/api/login/”)
调用登录名(@Field(“用户名”)字符串用户名,@Field(“密码”)字符串密码);
}

为什么您认为用户名和密码应该出现在路径上?我遵循“您好,先生,我遵循您所说的,我收到了此错误”java.lang.IllegalArgumentException:无法为接口改型创建调用适配器2.调用“mr@Jenea Vranceanu,我尝试并分析了您的答案,但是我遇到了这个错误,““”java.lang.ClassCastException:com.smartherd.globofly.services.UserService$AuthenticationResponse不能转换为com.smartherd.globofly.services.ResObj”“”嘿,伙计,你是个天才!非常感谢你。它可以工作:)您好,@brckner先生,您好,我尝试了您的答案,我从我的LoginActivity“”java.lang.IllegalArgumentException收到此错误:无法为接口2创建调用适配器。调用“”我想您遇到了此错误,因为调用类型必须参数化。尝试呼叫登录。。。。我已编辑了我的答案。“”java.lang.NullPointerException:尝试在空对象引用“”上调用虚拟方法“java.lang.String com.smartherd.globofly.services.ResObj.getMessage()”。啊,您正在从终结点返回令牌,因此您的调用不能参数化为Void。我已经编辑了我的答案。也许您还需要自定义一些其他代码,因为我更改了ResObj类,所以Gson可以自动解析响应。如果它仍然不起作用,可以尝试确定http端点上需要哪些数据,并阅读“如何正确发送”中的一些内容。
@POST("https://www.url.com/api/login/{username}/{password}")
Call login(@Path("username") String username, @Path("password") String password);