定义各类Api接口
Retrofit为我们提供了丰富的标签来实现不同的请求方式,
定义请求的样式如下:
@GetObservable<T> fetch();
请求类型
每个请求类型Retrofit都提供了相应的标签,如下:@GET @POST @PUT @DELETE
这些接口都支持一个字符串作为参数输入,像这样:@GET("user/token")
传入的路径为相对路径,这些会加到在配置时设置的BaseUrl
后面
这个路径可以使用{}包裹一个变量名,这样就可以在参数中传入这个变量名来修改请求的路径:
@GET("group/{id}/users") Observable<User> groupList(@Path("id") int groupId);
GET请求
使用注解@Query
@GET("group/{id}/users") Observable<User> groupList(@Path("id") int groupId,@Query("sort")String sort);
对应的url像这样baseUrl/group/id/users?sort=sort
如果有多个参数还可以使用@QueryMap
@GET("group/{id}/users") Observable<User> groupList(@Path("id") int groupId,@QueryMap Map<String, String> options);
对于下载文件或者下载图片可能需要修改整个url,而且这个时候想要获得的是原始返回的内容,可以把返回类型设置ResponseBody
即OkHttp的返回
@GETObservable<ResponseBody> downloadFile(@Url String url,@Header("Range")String range);
上面出现了@Header 使用来设置请求头信息,如果需要变化可以使用@Header在参数中设置,如果不用变化则使用@Headers 设置在方法上
@Headers("Cache-Control: public,max-age=640000")@GET("flight/choose-city") Observable<SelectCityList> getCitySearchList();@Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App"})@GET("users/{username}") Observable<User> getUser(@Path("username") String username);
POST请求
提交一个Json格式的Post请求
@POST("user/login") Observable<User> login(@Body LoginRequest loginRequest);
会对LoginRequest
使用Gson解析为json字符串发送请求
提交一个POST表单
@FormUrlEncoded@POST("user/user-feed-back") Observable<JSONObject> feedback(@Field("content") String content);
注意一定要写上@FormUrlEncoded,对于多个Field 也有@FieldMap
当然也可以提交一个原始的OkHttp请求,修改下登陆接口:
@POST("user/login") Observable<User> login(@Body RequestBody loginRequest);
关于@Multipart
@Multipart@PUT("user/photo") Observable<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
Retrofit提供了一些封装,其他不能解决情况可以直接使用RequestBody 和 ResponseBody
GSON解析辅助
默认的Gson解析有时不能满足业务的需求,可能需要设置对Gson进行一些配置
.addConverterFactory(GsonConverterFactory.create(new Gson()))
可以在配置Gson转换时传入我们另行配置的Gson
比如我们想要对所有的解析异常都不报错,而是设置为null。
final static class SafeTypeAdapterFactory implements TypeAdapterFactory{ @Override public TypeAdapter create(Gson gson, final TypeToken type) { final TypeAdapter delegate = gson.getDelegateAdapter(this,type); return new TypeAdapter() { @Override public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } @Override public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { in.skipValue(); return null; } catch (IllegalStateException e) { in.skipValue(); return null; } catch (JsonSyntaxException e) { in.skipValue(); if(type.getType() instanceof Class){ try { return (T) ((Class)type.getType()).newInstance(); } catch (Exception e1) { } } return null; } } }; } }
Gson myGson = new GsonBuilder().registerTypeAdapterFactory(new SafeTypeAdapterFactory().create());