Query注解
interface QueryGET{ @GET("/sheet") String getString(@Query("name")String name,@Query("age") int age,@QueryMap(encodeNames=true) Map<String, String> filters); }
模擬一個網絡請求
String url="http://tieba.baidu.com"; RestAdapter adapter =new RestAdapter.Builder().setEndpoint(url).setConverter(new StringConverter()).build(); QueryGET create = adapter.create(QueryGET.class); Map<String,String> map=new HashMap<String, String>(); map.put("gender", "male"); map.put("address", "sz"); String string = create.getString("laiqurufeng", 22, map);
query 訪問的參數會添加到路徑(path)的后面.
encodeNames=true表示對url的query進行url編碼,同理還有encodeValues. 這2個的值默認都是true的
如果上面的代碼換成 map.put("性別","男") ,然后更改@QueryMap(encodeNames=false )
那么實際訪問的url變成了
http://tieba.baidu.com/sheet?name=laiqurufeng&age=22&性別=%E7%94%B7&address=sz (可以看到key沒有進行url編碼,value進行了url編碼).
Field和Part注解
我們也可以在post請求的時候發送form-data和multipart-data.
表單數據要使用@FormUrlEncoded注解. 每一對鍵值對都要用@Field進行注解, 包括名字和value對象的值.
@FormUrlEncoded @POST("/user/edit") User updateUser(@Field("first_name") String first, @Field("last_name") String last);
用@Multipart注解來發送multipart-data,每一個part用@part注解.
@Multipart @PUT("/user/photo") User updateUser(@Part("photo") TypedFile photo, @Part("description") TypedString description);
Header注解
header分為key和value都固定,靜態Header注解方法 和 動態Header注解方法
注意header不會相互覆蓋.
interface FixedHeader{ @Headers({ //靜態Header "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" }) @GET("/") Response getResponse(); }
動態Header
interface DynamicHeader{ @Headers("Cache-Control: max-age=640000") //靜態Header @GET("/") Response getResponse(@Header("header1")String header1,@Header("header2")String header2); //動態Header,其value值可以在調用這個方法時動態傳入. }
同步和異步
有返回值的方法是同步執行的.如
@GET("/user/{id}/photo") Photo getUserPhoto(@Path("id") int id);
如果想采用異步執行的話,需要方法的最后一個參數是CallBack且返回值類型是void
interface AsychronousClient{ @GET("/") void getResponse(Callback<String> callback); //如果使用異步的方式的話,特別注意這里方法的返回值必須是void,Response轉化成的對象類型寫在CallBack<>的泛型中. }
在Android平台上,callbacks中的語句在主線程執行.(網絡訪問的部分在子線程中執行),如果是桌面應用的話,callbacks執行線程和Http訪問的線程是同一個線程.
如果方法采用異步的方式,並且返回值不是void,運行時就會拋出如下異常.
java.lang.IllegalArgumentException: xxx Must have return type or Callback as last argument, not both.
異步方式的retrofit可以直接在主線程中運行.
注意,異步方式的retrofit網絡訪問還是在子線程中運行的.但CallBack的success()和failure()方法是在主線程中運行的.(通過Android的Hanlder機制實現的)
RestAdapter adapter=new RestAdapter.Builder().setEndpoint("http://www.baidu.com").setConverter(new StringConverter()).build(); AsychronousClient create = adapter.create(AsychronousClient.class); create.getResponse(new Callback<String>() { @Override public void success(String str, Response response) { //第一個參數String就是通過我們自己實現的StringConverter把response轉換成String了.訪問成功時執行 } @Override public void failure(RetrofitError paramRetrofitError) { //訪問失敗時執行,比如說返回碼是40x,50x或者出現IO異常 } });