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异常 } });