安卓日記——用Retrofit寫一個登入註冊APP
阿新 • • 發佈:2018-12-30
在上一篇文章 Python日記——做一套簡易的註冊登入系統中,我簡單介紹瞭如果做一個登入註冊系統,但最終還是要安卓或者網頁是實現這個登入註冊行為
這裡我用一個非常流行的安卓網路請求庫Retrofit去演示這個過程
首先寫網路的介面
public interface MyService {
public static String base_url="你的伺服器地址";
@POST("api/users")
//表明傳的是json格式
@Headers({"Content-Type: application/json"})
Observable<UserBean> login(@Body PostUser user);
@GET("api/token")
Observable<TokenBean> getToken(@Header("Authorization")String auth);
@GET("api/resource")
Observable<DataBean> useToken(@Header("Authorization")String auth);
}
在註冊時可以直接post一個物件是因為下面使用的GsonConverterFactory幫我們將物件轉化為json
別忘了宣告頭部是json內容
然後寫ServiceFactory
public class ServiceFactory {
public static <T> T getService(Class<T> clazz) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(MyService.base_url)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(clazz);
}
}
註冊功能
根據圖可以看到傳送和接受資料的格式
我們新建兩個Bean
public class PostUser {
private String username;
private String password;
public PostUser(String username,String password){
this.username=username;
this.password=password;
}
}
public class UserBean {
private String username;
public String getUsername() {
return username;
}
}
邏輯程式碼是
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myService.login(new PostUser("jack123","ok"))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<UserBean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this,"Error:"+e.toString(),Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(UserBean userBean) {
tv.setText(userBean.getUsername());
}
});
}
});
登入功能
根據圖可以看到我們是使用Basic Auth的形式進行登入的,在我們的程式碼中使怎麼實現的呢
其實是通過新增一個Authorization的頭部,然後將“使用者名稱:密碼”轉化為Base64位編碼傳上去,前面還要加上Basic+空格
新建一個接受收據的Bean
public class TokenBean {
private String token;
private String duration;
public String getToken() {
return token;
}
public String getDuration() {
return duration;
}
}
邏輯程式碼是
btnGetToken.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String credentials="jack123:ok";
final String basic =
"Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
myService.getToken(basic)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<TokenBean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this,"Error:"+e.toString(),Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(TokenBean tokenBean) {
token=tokenBean.getToken();
tv.setText(tokenBean.getToken());
}
});
}
});
使用oken
可以看到是直接在使用者名稱上寫上token的
也要寫一個接受資料的Bean
public class DataBean {
private String data;
public String getData(){
return this.data;
}
}
邏輯程式碼是
btnUseToken.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String credentials=token;
String basic ="Basic " +Base64.encodeToString(credentials.getBytes(),Base64.NO_WRAP);
Log.e("basic",basic);
myService.useToken(basic)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<DataBean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Toast.makeText(MainActivity.this,"Error:"+e.toString(),Toast.LENGTH_SHORT).show();
}
@Override
public void onNext(DataBean dataBean) {
tv.setText(dataBean.getData());
}
});
}
});
然後點選這個按鈕時會報錯
retrofit2.adapter.rxjava.HttpException: HTTP 500 INTERNAL SERVER ERROR
然後我把postman轉化後的token和我的程式裡轉化的token對比
程式裡的
ZXlKaGJHY2lPaUpJVXpJMU5pSXNJbVY0Y0NJNk1UUTNNekUxTmpJeE9Dd2lhV0YwSWpveE5EY3pNVFUxTmpFNGZRLmV5SnBaQ0k2Tm4wLlpWYW5uN25SWmUyVk5UMVhJM3h3NEVoUllEMFkyTlhjTmUzMjBOTDR5VzA=
postman裡的
ZXlKaGJHY2lPaUpJVXpJMU5pSXNJbVY0Y0NJNk1UUTNNekUxTmpJeE9Dd2lhV0YwSWpveE5EY3pNVFUxTmpFNGZRLmV5SnBaQ0k2Tm4wLlpWYW5uN25SWmUyVk5UMVhJM3h3NEVoUllEMFkyTlhjTmUzMjBOTDR5VzA6
發現最後一位不同
然後我就把最後改為6在傳進去,果然成功了。
一套簡單的註冊登入系統就這樣完成了。