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