Retrofit2.0 的初步使用
最近编写的程序中设计到了Retrofit2.0 然后去整合OkHttpClient 设计成一个通用API,供其他的项目之间进行数据的传递。
最近有时间把它重新整理了下,具体的可以下载看下(gitHub地址:https://github.com/yihec/Retrofit-OkhttpClient.git)
我也是刚刚才使用所以说叫我讲啥原理我肯定不怎么会讲,所以这里就是告诉大家怎么使用,里面可能有些代码不怎么好,希望大家一起指出来,我会慢慢改正,请大家见谅。
首先我是把Retrofit2.0跟OkHttpClient 一起封装在RestCline中,当然也可以单独使用Retrofit,用法都是一样的,这里面因为加入了Gosn转化器,所以需要添加Gson依赖包, 我这个版本是可以用的之前好像用的是Gson2.4的版本,然后在使用的时候一直报没找到Gson包中的JsonWrite这个类的错误,好像是这个 。
Maven1 23 7 8com.squareup.retrofit2 4converter-gson 52.0.1 69 com.google.code.gson 10gson 112.6.1 12
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的四种方法。
1 @Headers("Content-Type: application/json; charset=utf-8")2 @GET("{apiVersion}/saibongs/items/")3 Callsearch(@Path("apiVersion") String apiVersion,@Query("number")Integer number);
@GET这里面有@Query,跟@QueryMap它会把参数以?number=3&….这种方式连接在url上面
@Path的作用就是: {apiVersion}/uses/items/ 比如apiVersion=v1,那么它的访问路径就是v1/uses/items1 interface Service { 2 /** 3 * 新增一条仓库定义记录**/ 4 @Headers("Content-Type: application/json; charset=utf-8") 5 @POST("{apiVersion}/stores/items/") 6 CalladdStore(@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 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 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 deleteStore(@Path("apiVersion") String apiVersion,@Path("code") String code);22 }
@POST里面的 @Body 是绑定一个对象
至于网上说的根据表单提交方式的不同 表单提交类型为@FormUrlEncoded跟它对应的就是@Field和@FieldMap,(表单默认提交为FormUrlEncoded) 表单提交类型为@Multipart的跟它对应的是@Part跟@PartMap 比如我这里面的那个根据map查询的那个方法,我直接就是把参数封装成对象然后用@Body可以正常访问,而用上面的那两种我都试了下都不行,至于是什么原因我也不是很清楚。 在使用之前你要create一下retrofit.create(StoreInfoService.class); }
然后再进行调用上面的方法
1 /** 2 * 查询服务目录记录**/ 3 public ListgetStoreList(Catalogue catalogue, Retrofit retrofit) throws IOException, IllegalArgumentException { 4 Call call = service.getStoreList(this.client.apiVersion(), catalogue); 5 List list=new ArrayList (); 6 Response bodyResponse = call.execute(); 7 if(bodyResponse.errorBody()!=null){ 8 Converter 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 () {19 }.getType()) ;20 PageUtil pa= datacenterResult.getPageUtil();21 list=pa.getList();22 }23 return list;24 }
bodyResponse.body().string()这里面存放的就是你的结果数据,我是用Gson把它转化成了一个对象
当然还可以直接定义那个类型的对象它可以自己转化//查询服务 @Headers("Content-Type: application/json; charset=utf-8") @POST("{apiVersion}/saibongs/") CallsearchSaibong(@Path("apiVersion") String apiVersion,@Body SaibongSearch sa) ; public List searchSaibong(SaibongSearch saibong, Retrofit retrofit) throws IOException, IllegalArgumentException { Call call = service.searchSaibong("v1", saibong); List list=new ArrayList (); Response bodyResponse = call.execute(); //这里面系统手动抛出的异常,自己定义的异常类型 if(bodyResponse.errorBody()!=null){ Converter 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包
Maven12 com.squareup.okhttp3 3mockwebserver 43.3.1 5
创建一个本地的服务
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(),"添加成功");
第一次把这几天弄出来的东西跟大家一起分享,希望能一起讨论--