[英]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
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
文档。
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
的文档。
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);
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.