Retrofit2.0 的初步使用css
最近編寫的程序中設計到了Retrofit2.0 而後去整合OkHttpClient 設計成一個通用API,供其餘的項目之間進行數據的傳遞。java
最近有時間把它從新整理了下,具體的能夠下載看下(gitHub地址:https://github.com/yihec/Retrofit-OkhttpClient.git)git
我也是剛剛纔使用因此說叫我講啥原理我確定不怎麼會講,因此這裏就是告訴你們怎麼使用,裏面可能有些代碼不怎麼好,但願你們一塊兒指出來,我會慢慢改正,請你們見諒。github
首先我是把Retrofit2.0跟OkHttpClient 一塊兒封裝在RestCline中,固然也能夠單獨使用Retrofit,用法都是同樣的,這裏面由於加入了Gosn轉化器,因此須要添加Gson依賴包, 我這個版本是能夠用的以前好像用的是Gson2.4的版本,而後在使用的時候一直報沒找到Gson包中的JsonWrite這個類的錯誤,好像是這個 。
Mavenweb
1 <!-- https://mvnrepository.com/artifact/com.squareup.retrofit2/converter-gson --> 2 <dependency> 3 <groupId>com.squareup.retrofit2</groupId> 4 <artifactId>converter-gson</artifactId> 5 <version>2.0.1</version> 6 </dependency> 7 <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> 8 <dependency> 9 <groupId>com.google.code.gson</groupId> 10 <artifactId>gson</artifactId> 11 <version>2.6.1</version> 12 </dependency>
1 public RestClient build() { 2 OkHttpClient httpClient = httpClientBuilder 3 .build(); 4 return new RestClient(httpClient, 5 retrofitBuilder 6 .baseUrl(baseUrl)//設置URL 7 .addConverterFactory(GsonConverterFactory.create())//添加Gosn轉換器 8 .client(httpClient) 9 .build() 10 ); 11 }
接下來的就是建立一個接口,我這裏寫了增刪改查,跟提交方式爲GET,POST,PUT,DELETE的四種方法。sql
1 @Headers("Content-Type: application/json; charset=utf-8") 2 @GET("{apiVersion}/saibongs/items/") 3 Call<Result> search(@Path("apiVersion") String apiVersion,@Query("number")Integer number);
@GET這裏面有@Query,跟@QueryMap它會把參數以?number=3&….這種方式鏈接在url上面
@Path的做用就是:
{apiVersion}/uses/items/ 好比apiVersion=v1,那麼它的訪問路徑就是v1/uses/itemsjson
1 interface Service { 2 /** 3 * 新增一條倉庫定義記錄**/ 4 @Headers("Content-Type: application/json; charset=utf-8") 5 @POST("{apiVersion}/stores/items/") 6 Call<ResponseBody> addStore(@Path("apiVersion") String apiVersion,@Body StoreInfo storeInfo); 7 /** 8 * 根據map中的參數查詢知足條件的倉庫定義記錄列表**/ 9 @Headers("Content-Type: application/json; charset=utf-8") 10 @POST("{apiVersion}/stores/list/") 11 Call<ResponseBody> getStoreList(@Path("apiVersion") String apiVersion,@Body StoreInfo storeInfo); 12 /** 13 * 修改倉庫定義記錄*/ 14 @Headers("Content-Type: application/json; charset=utf-8") 15 @PUT("{apiVersion}/stores/items/{code}") 16 Call<ResponseBody> editStore(@Path("apiVersion") String apiVersion,@Path("code") String code,@Body StoreInfo storeInfo); 17 /** 18 * 刪除倉庫定義記錄*/ 19 @Headers("Content-Type: application/json; charset=utf-8") 20 @DELETE("{apiVersion}/stores/items/{code}") 21 Call<ResponseBody> deleteStore(@Path("apiVersion") String apiVersion,@Path("code") String code); 22 }
@POST裏面的 @Body 是綁定一個對象
至於網上說的根據表單提交方式的不一樣
表單提交類型爲@FormUrlEncoded跟它對應的就是@Field和@FieldMap,(表單默認提交爲FormUrlEncoded)
表單提交類型爲@Multipart的跟它對應的是@Part跟@PartMap
好比我這裏面的那個根據map查詢的那個方法,我直接就是把參數封裝成對象而後用@Body能夠正常訪問,而用上面的那兩種我都試了下都不行,至因而什麼緣由我也不是很清楚。
在使用以前你要create一下api
retrofit.create(StoreInfoService.class); }
而後再進行調用上面的方法markdown
1 /** 2 * 查詢服務目錄記錄**/ 3 public List<StoreInfo> getStoreList(Catalogue catalogue, Retrofit retrofit) throws IOException, IllegalArgumentException { 4 Call<ResponseBody> call = service.getStoreList(this.client.apiVersion(), catalogue); 5 List<StoreInfo> list=new ArrayList<StoreInfo>(); 6 Response<ResponseBody> bodyResponse = call.execute(); 7 if(bodyResponse.errorBody()!=null){ 8 Converter<ResponseBody, ErrorMsg> errorConverter = 9 retrofit.responseBodyConverter(ErrorMsg.class, new Annotation[0]); 10 // 錯誤類型 11 ErrorMsg error = errorConverter.convert(bodyResponse.errorBody()); 12 if(error!=null){ 13 error.setStatus(bodyResponse.code()+""); 14 throw new DataCenterException(error); 15 } 16 }else{ 17 Gson gson=new Gson(); 18 DatacenterResult datacenterResult= gson.fromJson(bodyResponse.body().string(), new TypeToken<DatacenterResult>() { 19 }.getType()) ; 20 PageUtil pa= datacenterResult.getPageUtil(); 21 list=pa.getList(); 22 } 23 return list; 24 }
bodyResponse.body().string()這裏面存放的就是你的結果數據,我是用Gson把它轉化成了一個對象
固然還能夠直接定義那個類型的對象它能夠本身轉化app
//查詢服務 @Headers("Content-Type: application/json; charset=utf-8") @POST("{apiVersion}/saibongs/") Call<SaibongResult> searchSaibong(@Path("apiVersion") String apiVersion,@Body SaibongSearch sa) ; public List<SaibongRules> searchSaibong(SaibongSearch saibong, Retrofit retrofit) throws IOException, IllegalArgumentException { Call<SaibongResult> call = service.searchSaibong("v1", saibong); List<SaibongRules> list=new ArrayList<SaibongRules>(); Response<SaibongResult> bodyResponse = call.execute(); //這裏面系統手動拋出的異常,本身定義的異常類型 if(bodyResponse.errorBody()!=null){ Converter<ResponseBody, ErrorMsg> errorConverter = retrofit.responseBodyConverter(ErrorMsg.class, new Annotation[0]); // 錯誤類型ErrorMsg 是我本身定義的 ErrorMsg error = errorConverter.convert(bodyResponse.errorBody()); if(error!=null){ error.setStatus(bodyResponse.code()+""); throw new SaibongException(error); } }else{ SaibongResult saibongResult= bodyResponse.body(); PageUtil pa= saibongResult.getPageUtil(); list=pa.getList(); } return list; }
這裏測試須要建立一個本地的服務,因此須要添加mockwebserver的jar包
Maven
1 <dependency> 2 <groupId>com.squareup.okhttp3</groupId> 3 <artifactId>mockwebserver</artifactId> 4 <version>3.3.1</version> 5 </dependency>
建立一個本地的服務
1 MockWebServer server = new MockWebServer(); //建立本地服務 2 server.start();//開啓服務 3 //建立鏈接對象 4 retrofit = new Retrofit.Builder() 5 .baseUrl(server.url("/")) 6 .addConverterFactory(GsonConverterFactory.create()) 7 .build(); 8 server.enqueue(new MockResponse() 9 .setResponseCode(404)//這裏設置你的http狀態碼 10 .setBody("這裏設置的是你的結果")); 11 Service service = retrofit.create(Service.class); 12 //調用方法 13 server.add(); 14 //這裏能夠用junit中的來比對結果 15 assertEquals(server.add(),"添加成功");
第一次把這幾天弄出來的東西跟你們一塊兒分享,但願能一塊兒討論--