简体   繁体   English

java.lang.IllegalArgumentException:URL“https:/my url/api/login/”不包含“{username}”。 (参数#1)

[英]java.lang.IllegalArgumentException: URL “https:/my url/api/login/” does not contain “{username}”. (parameter #1)

I am new in android studio, and i am doing login activity using java, retrofit and web api (django restframework). I am new in android studio, and i am doing login activity using java, retrofit and web api (django restframework). i am getting this error, java.lang.IllegalArgumentException: URL "https:// my url /api/login/" does not contain "{username}".我收到此错误, java.lang.IllegalArgumentException: URL "https:// my url /apiname}/login" 不包含 "/" (parameter #1) for method UserService.login , why i am getting this error? (参数#1)方法 UserService.login ,为什么我收到此错误? eventhough my web api is working?尽管我的 web api 工作正常吗?

this is my post data这是我的帖子数据

在此处输入图像描述

this is my LoginActivity.java这是我的 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();
            }
        });
    }
}

my UserService我的用户服务

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

}

this is my RetrofitClient这是我的 RetrofitClient

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;
    }
}

my ResObj我的 ResObj

public class ResObj {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

my ApiUtils我的 APIUtils

public class ApiUtils {

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

    public static UserService getUserService(){
        return RetrofitClient.getClient(BASE_URL).create(UserService.class);
    }
}

this is my full error I receive这是我收到的全部错误

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

Update更新

For @POST type of requests, you can also use @Field to pass individual fields of form-encoded request.对于@POST类型的请求,您还可以使用@Field传递表单编码请求的各个字段。

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

Documentation of @Field with examples.带有示例的@Field文档。

To process the response:要处理响应:

Define a simple class AuthenticationResponse :定义一个简单的 class AuthenticationResponse

public class AuthenticationResponse {
    public String token;
}

And use it as a generic type parameter of your login call:并将其用作login调用的通用类型参数:

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

Using AuthenticationResponse will require an update of your LoginActivity method doLogin :使用AuthenticationResponse将需要更新您的LoginActivity方法doLogin

private void doLogin(final String username, final String password) {
    Call<AuthenticationResponse> call = userService.login(username, password);
    call.enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) {
            if (response.isSuccessful()) {
                AuthenticationResponse authResponse = (AuthenticationResponse) response.body();
                if (!TextUtils.isEmpty(authResponse.token)) {
                    //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();
        }
    });
}

For @POST type of requests if you need your parameters to be part of the request body then you must annotate those parameters with @Body annotation.对于@POST类型的请求,如果您需要将参数作为请求正文的一部分,那么您必须使用@Body注释来注释这些参数。 But you can you only one @Body annotation as the parameter declared with that annotation will define the whole body of a request.但是您可以只使用一个@Body注释,因为使用该注释声明的参数将定义请求的整个主体。

@POST("https://www.url.com/api/login/")
Call login(@Body Credentials credentials);

Where Credentials is a POJO class:其中Credentials是 POJO class:

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

Documentation of @Body . @Body的文档。

Why exactly error happens?为什么会发生错误?

When you use @Path("name") annotation you must provide a placeholder for that path argument in your URL.当您使用@Path("name")注释时,您必须在 URL 中为该路径参数提供一个占位符。

Instead of:代替:

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

Your POST call declaration should look like this, so the Retrofit will know where to place these path arguments:您的 POST 调用声明应如下所示,因此 Retrofit 将知道将这些路径 arguments 放置在何处:

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

Documentation of @Path with examples.带有示例的@Path文档。

Is your login http endpoint expecting, that you're sending the login data (username, password) as urlencoded parameters in the body?您的登录 http 端点是否期望您将登录数据(用户名、密码)作为正文中的 urlencoded 参数发送? Then try to modify your UserService interface like this:然后尝试像这样修改您的 UserService 接口:

public class ResObj {
    private String token;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }
}

public interface UserService {
    @FormUrlEncoded
    @POST("https:// my url /api/login/")
    Call<ResObj> login(@Field("username") String username, @Field("password") String password);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java.lang.IllegalArgumentException:@Url不能与@GET URL一起使用(参数#1) - java.lang.IllegalArgumentException: @Url cannot be used with @GET URL (parameter #1) java.lang.IllegalArgumentException:“ json”不包含“ /” - java.lang.IllegalArgumentException: “json” does not contain '/' - java.lang.IllegalArgumentException: 无效的 url: - - java.lang.IllegalArgumentException: Invalid url: 编码的URL和java.lang.IllegalArgumentException - Encoded URL and java.lang.IllegalArgumentException restTemplate java.lang.IllegalArgumentException:“无”不包含“ /” - restTemplate java.lang.IllegalArgumentException: “None” does not contain '/' java.lang.IllegalArgumentException:参数不作为命名参数存在 - java.lang.IllegalArgumentException: Parameter does not exist as a named parameter in Java 中 URL 路径中的 java.lang.IllegalArgumentException - java.lang.IllegalArgumentException in URL's path in Java 内容提供者未知URL java.lang.IllegalArgumentException错误 - Content Provider Unknown URL java.lang.IllegalArgumentException Error 获取错误java.lang.IllegalArgumentException:意外的url - Getting Error java.lang.IllegalArgumentException: unexpected url java.lang.IllegalArgumentException:无法解析占位符“BASE_URL” - java.lang.IllegalArgumentException: Could not resolve placeholder 'BASE_URL'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM