開題:在此默認各位看官對Retrofit、以及Okhttp已經有過一定的了解及應用,所以今天我們不談基礎入門的東西,今天我們談在Retrofit請求接口管理類中URL參數含有動態參數的處理方式。一般我們使用Retrofit大部分場景中URL都是以注解的方式靜態聲明的,即URL及path路徑都是固定不變,可變部分作為方法的參數傳入,那有一些特殊情況會要求我們再使用@GET()、或者@POST()的時候URL路徑里含有可變參數,需要動態處理,下面通過例子我逐個為大家分析講解。
說明:以下所有Retrofit請求的BaseURL為https://192.168.1.101/api/,接口地址為本地測試,不代碼以下接口真實可用
1.GET請求
1.)普通get請求
https://192.168.1.101/api/MovieList
@GET("MovieList") Observable<ResultEntity<MovieEntity>> getMovieList();
2.) url中含有參數
https://192.168.1.101/api/MovieList/2018
分析:2018為動態可變部分,代表指定idMovie,api/MovieList/{movieId}
@GET("MovieList{movieId}") Observable<ResultEntity<MovieEntity>> getMovieList(@Path("movieId") String movieId );
或者
https://192.168.1.101/api/MovieList/2018/comedy
分析:請求指定年下類型為comedy的電影,可變部分為年份/類型 請求地址可變部分歸類為 api/{movieId}/{type}
@GET("MovieList{movieId}/{type}") Observable<ResultEntity<MovieEntity>> getMovieList(@Path("movieId") String movieId ,@Path("type") String type);
3.)可變參數在URL的問號之后
https://192.168.1.101/api/MovieList?movieId=10011
分析:問號之后的參數可以直接用@Query注解在作為方法參數傳入
@GET("MovieList") Observable<ResultEntity<MovieEntity>> getMovieList(@Query("movieId") String movieId);
4.) 問號后面有多個參數 :
https://192.168.1.101/api/MovieList?movieId=10011&type=3
@GET("MovieList") Observable<ResultEntity<MovieEntity>> getMovieList(@Query("movieId") String movieId,@Query("type") int type);
5.)問號后面有多個參數,且參數個數不定
https://192.168.1.101/api/MovieList?movieId=10011&type=4&year=2013&......
分析:作為Get請求,后面參數根據具體業務確定參數多少,也就是參數個數可變,但不確定多少個,可以借助@Querymap
@GET("MovieList") Observable<ResultEntity<MovieEntity>> getMovieList(@QueryMap Map<String ,Object> map);
2.POST請求
1.) url中含有可變參數,post的數據只有一個type
https://192.168.1.101/api/MovieList/2018
分析:url中2018為可變內容,post需要提交的參數只有一個type,2018可動態改變
@FormUrlEncoded @POST("MovieList/{movieId}") Observable<ResultEntity<MovieEntity>> getMovieList(@Path("movieId") String movieId, @Field("type") String type);
2.) url中含有可變參數、問號之后需要加入token,post的數據只有一個type
https://192.168.1.101/api/MovieList/2018?token=4654551321563132fasd5645ds3
@FormUrlEncoded @POST("MovieList/{movieId}") Observable<ResultEntity<MovieEntity>> getMovieList(@Path("movieId") String movieId, @Query("token") String token, @Field("type") String type);
3.) url中含有可變參數、問號之后需要加入token,post的數據為一個對象(json串)
https://192.168.1.101/api/MovieList/2018?token=4654551321563132fasd5645ds3
@POST("MovieList/{movieId}") Observable<ResultEntity<MovieEntity>> getMovieList(@Path("movieId") String movieId, @Query("token") String token, @Body MovieEntity entity);
以上內容 轉自:https://blog.csdn.net/xieluoxixi/article/details/80092582
另外還有幾點
1.如果你的可變參數中是帶斜杠“/”的,比如https://192.168.1.101/api/MovieList/session/token,
session和token都是可變參數,但session是已知的,只是可能不同的請求下要求變為不同的字段,如
https://192.168.1.101/api/MovieList/apiKey/token,而baseURL始終為https://192.168.1.101/api/MovieList/
@POST("session/{movieId}") Call<ResponseBody> getSessionKey(@Path(value = "movieId", encoded = true) String movieId, @Body RequestBody req);
2.如果你需要用到delete請求,比如
@DELETE("event/{uuid}") Observable<ResponseBody> delEvent(@Path(value = "uuid", encoded = true) String uuid, @Body RequestBody rb);
直接這樣用就會報錯java.lang.IllegalArgumentException:Non-body HTTP method cannot contain @Body
據說官網表示DELETE並不支持向服務器傳body
必須更換一下寫法:
@HTTP(method = "DELETE",path = "event/{uuid}",hasBody = true) Observable<ResponseBody> delEvent(@Path(value = "uuid", encoded = true) String uuid, @Body RequestBody rb);