1. 程式人生 > >Retrofit2提交JSON格式的資料

Retrofit2提交JSON格式的資料

  為了跟上Android開發的技術潮流,最近在研究Retrofit。自己也嘗試在此基礎上封裝適合自己的網路請求框架。工作的專案中所有請求都約定為POST並且請求引數和響應結果都是JSON格式的。於是開始搜尋“Retrofit提交JSON“,得到的結果和Retrofit的官方簡介上推薦的一樣的。那就是把請求封裝成bean,然後使用@Body來發送這個請求。程式碼如下

public interface TaskService {
    @POST("/tasks")
    Call<Task> createTask(@Body Task task);
}
public class
Task { private long id; private String text; public Task(long id, String text) { this.id = id; this.text = text; } }
Task task = new Task(1, "my task title");  
Call<Task> call = taskService.createTask(task);  
call.enqueue(new Callback<Task>() {});  

  上述程式碼的掣肘顯而易見,那就是需要為每個請求都封裝一個bean。使用這種方式的博友們還專門提供了自動生成這樣的bean的工具類,可謂良苦用心。Java Web開發中也許習慣以bean作為查詢條件,每張資料庫表對應一個bean,很容易獲得。即使bean中很多欄位根本用不到,但是簡單粗暴將整個bean傳過去作為引數,使用起來非常方便。而以移動端的開發習慣,我們並不會為每個request封裝一個特定的bean。而只會為每個response封裝一個bean或者叫model,用於反序列化響應結果。
  下面看看Retrofit提交JSON的正確姿勢。

//定義介面
public interface
ApiService {
/** * request和response都是json形式,不使用系統預設的GsonConverter,拿到response後自己用Gson解析成bean */ @POST Call<ResponseBody> postWithJson(@Url String url, @HeaderMap Map<String, String> headers, @Body RequestBody paramBody); }

這裡的@HeaderMap是新增動態請求頭用的,比如cookie。不需要的可以去掉headers這個引數。

//封裝
@Override
    public Call<ResponseBody> generateCall() {
        RequestBody paramBody = RequestBody.create(MediaType.parse("application/json;charset=UTF-8"), mParamStr);//將引數包裝成RequestBody
        return HttpRequest.sApiService.postWithJson(mUrl, mHeaderMap, paramBody);
    }
mCall = mBuilder.generateCall();
mCall.enqueue(callback);

如果對你有幫助,這是生成代理物件的程式碼

public class ServiceGenerator {
    private static OkHttpClient.Builder okHttpclientBuilder;
    private static Retrofit.Builder retrofitBuilder;

    public static <S> S createService(Class<S> serviceClass) {
        okHttpclientBuilder = new OkHttpClient.Builder();
        //目前封裝的幾個介面都是沒有用到GsonConverter,是傳入ResponseBody,拿到響應結果後自己解析
        retrofitBuilder = new Retrofit.Builder() .baseUrl(Config.baseUrl)
        /*.addConverterFactory(GsonConverterFactory.create())*/;
        Retrofit retrofit = retrofitBuilder.client(okHttpclientBuilder.build()).build();
        return retrofit.create(serviceClass);
    }
}
public static ApiService sApiService = ServiceGenerator.createService(ApiService.class);

以及實際使用的程式碼

HttpRequest.builder(
    new PostJsonBuilder()
        .url(ApiUrl.LOGIN)
                .defaultHeaders()
                .param("mobile", "13*********")
                .param("password", Md5.md5Toword("123456"))
                .modelClazz(LoginModel.class)
                .callback(new AbsCallback<LoginModel>() {
                    @Override
                        public void onBizSuccessOnUi(LoginModel model) {
                            UserInfo info = model.getData();
                            ToastUtils.showShort("登入成功");
                            mBtnLogin.setText("登入成功");
                        }

                        @Override
                        public void onBizFailureOnUi(LoginModel model) {
                            ToastUtils.showShort("登入失敗");
                        }
                    })).startCall();