国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android中Retrofit 2.0直接使用JSON進行數據交互

2019-10-22 18:29:30
字體:
來源:轉載
供稿:網友

之前使用Retrofit都是將JSON串轉化為POJO對象,針對不同的業務協議,定義相應的接口和參數列表。但是此種方式一般用在自己內部協議基礎上,具體大的項目中,有些第三方的集成功能,一般都采用統一的方式即請求JSON和回應JSON進行數據交互,不可能每個第三方協議都會去定義與協議相應的POJO對象。

HTTP肯定有GET和POST方法,先定義Retrofit Api的interface:

package com.hdnetworklib.network.http;import java.util.Map;import okhttp3.RequestBody;import okhttp3.ResponseBody;import retrofit2.Call;import retrofit2.http.Body;import retrofit2.http.GET;import retrofit2.http.POST;import retrofit2.http.QueryMap;import retrofit2.http.Url;/** * Created by wangyuhang@evergrande.cn on 2017/8/23 0023. */public interface RetrofitServiceApi {  @POST  Call<ResponseBody> reqPost(@Url String url, @Body RequestBody requestBody);  @GET  Call<ResponseBody> reqGet(@Url String url, @QueryMap Map<String, String> options);  @GET  Call<ResponseBody> reqGet(@Url String url);}

1、POST方式,采用指定完整的URL,reqeustBody就是后面業務要傳入的完整JSON串

2、GET方式,后面的options就是一個Map,業務參數鍵值就存在這個里面,URL里面不需要帶值。

3、GET方式,與2不同的是沒有options,這樣就鍵值對全部帶在URL里面,類似于這樣的格式:http://112.124.22.238:8081/course_api/wares/hot?pageSize=1&curPage=1

接下來就是具體對業務的接口了,提供POST和GET兩個請求接口調用:

package com.hdnetworklib.network.http;import android.util.Log;import java.io.IOException;import java.util.Map;import okhttp3.MediaType;import okhttp3.RequestBody;import okhttp3.ResponseBody;import retrofit2.Call;import retrofit2.Callback;import retrofit2.Response;import retrofit2.Retrofit;import retrofit2.converter.gson.GsonConverterFactory;/** * Created by wangyuhang@evergrande.cn on 2017/7/12 0012. */public class HttpClient {  private static final String TAG = "HttpClient";  private static volatile HttpClient instance;  private HttpClient() {  }  public static HttpClient getInstance() {    if (instance == null) {      synchronized (HttpClient.class) {        if (instance == null) {          instance = new HttpClient();        }      }    }    return instance;  }  /**   * Http Post請求   *   * @param req_id  請求編號   * @param method  請求業務方法   * @param url   請求的URL   * @param jsonData POST需要所帶參數(JSON串格式)   * @param callback 回調接口   */  public void reqPostHttp(final int req_id, final String method, String url, String jsonData, final HttpCallback callback) {    Retrofit retrofit = new Retrofit.Builder()        .baseUrl("http://www.what.com/")        .addConverterFactory(GsonConverterFactory.create())        .build();    RetrofitServiceApi retrofitServiceApi = retrofit.create(RetrofitServiceApi.class);    RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonData);    Call<ResponseBody> call = retrofitServiceApi.reqPost(url, body);    call.enqueue(new Callback<ResponseBody>() {      @Override      public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {        try {          String result = response.body().string();          Log.i(TAG, "reqPostHttp onResponse: " + result);          if (callback != null) {            callback.onSuccess(new HttpResMsg(req_id, method, result));          }        } catch (IOException e) {          e.printStackTrace();          Log.e(TAG, "reqPostHttp onResponse exception: " + e.toString());          if (callback != null) {            callback.onError(e.toString());          }        }      }      @Override      public void onFailure(Call<ResponseBody> call, Throwable t) {        Log.e(TAG, "reqPostHttp onFailure: " + t.toString());        if (callback != null) {          callback.onError(t.toString());        }      }    });  }  /**   * Http Get請求   *   * @param req_id  請求編號   * @param method  請求業務方法   * @param url   請求的URL   * @param options GET需要所帶參數鍵值(如果URL里帶有則不需要在此添加)   * @param callback 回調接口   */  public void reqGetHttp(final int req_id, final String method, String url,              Map<String, String> options, final HttpCallback callback) {    Retrofit retrofit = new Retrofit.Builder()        .baseUrl("http://www.what.com/")        .addConverterFactory(GsonConverterFactory.create())        .build();    RetrofitServiceApi retrofitServiceApi = retrofit.create(RetrofitServiceApi.class);    Call<ResponseBody> call = null;    if (options == null) {      call = retrofitServiceApi.reqGet(url);    } else {      call = retrofitServiceApi.reqGet(url, options);    }    call.enqueue(new Callback<ResponseBody>() {      @Override      public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {        try {          String result = response.body().string();          Log.i(TAG, "reqPostHttp onResponse: " + result);          if (callback != null) {            callback.onSuccess(new HttpResMsg(req_id, method, result));          }        } catch (IOException e) {          e.printStackTrace();          Log.e(TAG, "reqPostHttp onResponse exception: " + e.toString());          if (callback != null) {            callback.onError(e.toString());          }        }      }      @Override      public void onFailure(Call<ResponseBody> call, Throwable t) {        Log.e(TAG, "reqPostHttp onFailure: " + t.toString());        if (callback != null) {          callback.onError(t.toString());        }      }    });  }}

需要注意的是:

baseUrl(http://www.what.com/)

這里的這個baseUrl是我瞎掰的一個地址,因為Retrofit的限制:如果baseUrl不是以 / 結尾就會報異常:

Caused by: java.lang.IllegalArgumentException: baseUrl must end in /

當我們需要完整的指定URL的時候,特別是上面列出的第二種GET方式,我們的URL是http://112.124.22.238:8081/course_api/wares/hot?pageSize=1&curPage=1,如果我們直接通過接口傳參把這個URL直接傳入baseUrl中,如下(注意最后沒有/結尾):

Retrofit retrofit = new Retrofit.Builder()        .baseUrl("http://112.124.22.238:8081/course_api/wares/hot?pageSize=1&curPage=1")        .addConverterFactory(GsonConverterFactory.create())        .build();

這樣運行時就會報錯。那如果我們手工在最后面加上一個/呢?如下(注意最后有/結尾):

Retrofit retrofit = new Retrofit.Builder()        .baseUrl("http://112.124.22.238:8081/course_api/wares/hot?pageSize=1&curPage=1/")        .addConverterFactory(GsonConverterFactory.create())        .build();

這樣運行時仍然報錯,而且你把這個鏈接復制到瀏覽器中看看就知道肯定不行的:http://112.124.22.238:8081/course_api/wares/hot?pageSize=1&curPage=1/

我一開始遇到這個問題的時候也是第一反應去查Retrofit的官方文檔和說明,或者讓第三方的開發人員采用第二種GET請求方式,用一個以 / 結尾的URL,然后把URL中?后面帶的那些值放到一個Map里傳進來。首先官方說明和Api用法沒找到,而且這個baseUrl還必須調用,其次,別的開發人員不愿意弄,好好的辛辛苦苦把URL都組裝好了,沒啥事讓我傳Map啊,肯定也不行。后面在這里找到了答案:https://stackoverflow.com/questions/36736854/retrofit2-how-do-i-put-the-at-the-end-of-the-dynamic-baseurl

Retrofit,JSON交互,Retrofit使用JSON交互

Retrofit,JSON交互,Retrofit使用JSON交互

所以既然你后面會完整指定URL,那么一開始的baseUrl就無關緊要,隨便寫一個以/結尾的Http地址就可以了。

剩下的的就是回調和消息的組裝了,各位可以根據自己的業務需求進行組裝和調整,我這里就只貼出代碼不做過多解析了。

回調接口:

package com.hdnetworklib.network.http;/** * Created by wangyuhang@evergrande.cn on 2017/8/23 0023. */public interface HttpCallback {  void onSuccess(HttpResMsg httpResMsg);  void onError(String errorMsg);}

消息結構的組裝:

package com.hdnetworklib.network.http;/** * Created by wangyuhang@evergrande.cn on 2017/8/23 0023. */public class HttpResMsg {  private Integer req_id;  private String method;  private String data;  public HttpResMsg() {  }  public HttpResMsg(int req_id, String method, String data) {    this.req_id = req_id;    this.method = method;    this.data = data;  }  public Integer getReq_id() {    return req_id;  }  public void setReq_id(Integer req_id) {    this.req_id = req_id;  }  public String getMethod() {    return method;  }  public void setMethod(String method) {    this.method = method;  }  public String getData() {    return data;  }  public void setData(String data) {    this.data = data;  }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 赤峰市| 中宁县| 丰宁| 乌兰县| 隆回县| 龙井市| 商城县| 郑州市| 清远市| 富蕴县| 大化| 南川市| 左贡县| 玉林市| 朝阳市| 芒康县| 菏泽市| 呈贡县| 太仆寺旗| 宜兰市| 开化县| 泽州县| 法库县| 冷水江市| 曲麻莱县| 盘锦市| 景东| 英山县| 钟山县| 石狮市| 乌拉特后旗| 喀喇沁旗| 萝北县| 巨鹿县| 华阴市| 崇仁县| 祁连县| 巴青县| 珠海市| 永康市| 托克逊县|