1. 程式人生 > >安卓日記——用Retrofit寫一個登入註冊APP

安卓日記——用Retrofit寫一個登入註冊APP

在上一篇文章 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
可以看到是直接在使用者名稱上寫上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在傳進去,果然成功了。

一套簡單的註冊登入系統就這樣完成了。