Android Retrofit2 实现 REST API 的登陆(一)

1. 先搞个有REST API的网站

之前用过retrofit1,想用用retrofit2

选了一个之前有搭过的开源web框架“GitLab” https://github.com/gitlabhq/gitlabhq

ubuntu安装参考:https://about.gitlab.com/installation/#ubuntu

浏览器输入自己的IP(或安装gitlab的服务器IP),就能看到自己GitLab

用README里介绍的默认用户名和密码登陆 地址后输入profile/personal_access_tokens,生成个private token,登陆认证时会用到

2. Android客户端

(1)新建工程

Android Studio 3.2 

“New”->“NewProject”-> 默认的“Login Activity”

添加
dependencies {

    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.4.0'

    implementation 'com.google.code.gson:gson:2.8.2'
    implementation 'net.danlaw:android.joda:2.9.9.2'
    implementation 'commons-io:commons-io:2.6'
    implementation 'commons-lang:commons-lang:2.6'
    implementation 'commons-codec:commons-codec:1.11'

}

(2)REST API 接口

Session类,用来处理登陆 session

public class Session {

    public String name;
    public String private_token;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getPrivateToken() {
        return private_token;
    }
    public void setPrivateToken(String private_token) {
        this.private_token = private_token;
    }

    ...
}

GitLabAPI类,Retrofit2 使用 REST API 的接口

import retrofit2.Call;
import retrofit2.http.POST;

public interface GitLabAPI {

    /* --- LOGIN --- */
    // retrofit2 改为 return Call 对象
    @POST("/session")
    Call getSessionByUsername(@Query("login") String login, @Query("password") String password);

    ...
}

okhttp3 创建拦截器

import java.io.IOException;

import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

public class GitLabInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        /**
         * 参考 help/api/README.md 的这条
         * curl --header "Private-Token: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects
         * */
        HttpUrl url = request.url().newBuilder().addQueryParameter(
                "PRIVATE-TOKEN", "").build();
        request = request.newBuilder().url(url).build();
        return chain.proceed(request);
    }
}

Retrofit2 实现 REST API

import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

import org.joda.time.format.ISODateTimeFormat;

    private static GitLabAPI service;

    public static GitLabAPI getService() {

        if (service == null) {
            // Configure Gson to handle dates correctly
            GsonBuilder gsonBuilder = new GsonBuilder();
            gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer() {
                @Override
                public Date deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
                    return ISODateTimeFormat.dateTimeParser().parseDateTime(json.getAsString()).toDate();
                }
            });
            Gson gson = gsonBuilder.create();

            OkHttpClient okHttpClient = new OkHttpClient().newBuilder().addInterceptor(new GitLabInterceptor()).build();
            Retrofit retrofit = new Retrofit.Builder()
                    .client(okHttpClient)
                    .baseUrl("http://" + "/api/v4/") // TODO: 用实际的地址代替
                    .addConverterFactory(GsonConverterFactory.create(gson))
                    .build();

            service = retrofit.create(GitLabAPI.class);
        }

        return service;
    }

创建回调对象

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.HttpException;
import retrofit2.Response;

private Callback sessionCallback = new Callback() {
        @Override
        public void onResponse(Call call, Response response) {
            // TODO: 登陆成功的处理
            Log.d("", "success");
        }

        @Override
        public void onFailure(Call call, Throwable t) {
            Log.e("", String.valueOf(t.fillInStackTrace()));
        }
    };

登陆,在LoginActivity的attemptLogin()里修改成

if (cancel) {
            // There was an error; don't attempt login and focus the first
            // form field with an error.
            focusView.requestFocus();
        } else {
            // Show a progress spinner, and kick off a background task to
            // perform the user login attempt.
            showProgress(true);
// Retrofit2 执行验证请求
            Call call = Repository.getService().getSessionByUsername(email, password); //记得把Email的“@”限制去掉,inputType改为text
            call.enqueue(sessionCallback);
// 因为enqueue已经时异步的了,不用再用AsyncTask了
//            mAuthTask = new UserLoginTask(email, password);
//            mAuthTask.execute((Void) null);
        }


你可能感兴趣的:(Android Retrofit2 实现 REST API 的登陆(一))