Retrofit 快速學習 註解詳解

一、Retrofit 註解脈絡圖java

二、請求類web

2.1.1 @GETjson

對應get網絡請求api

結合@Path、@Query、@QueryMap使用跨域

GET後面的url中可使用自定義的變量,如 {id}、{userId}進行站位 ,並使用 @Path("id") 、@Path("userId") 註解爲 {id} 、{userId} 提供值緩存

以下:注意形如形如「?page/xxx/id/aaa」才能使用@Path來拼接url安全

@GET("page/{index}/id/{id}")
Call<ImageBeans> requestImage(@Path("key") int index,@Path("id") int id);

可是可能有人會想到既然是佔位符,那麼下面的方式能夠嗎?服務器

@GET("?app=weather.future&weaid=1&&appkey={key}")
Call<WeatherBeans> requestWeather(@Path("key") int key);

答案是不能夠,會報錯網絡

java.lang.IllegalArgumentException: URL query string "app=weather.future&weaid=1&&appkey={key}" must not have replace block. For dynamic query parameters use @Query.app

形如「?a=xxxx&b=xxxx&c=xxxx」的url是不能用@PATH註解來拼接的,應該使用@Query或者@QueryMap註解,以下:

 

@Query

一、接口定義
@GET("?")
Call<WeatherBeans> requestWeather(@Query("app") String app ,@Query("weaid") int weaid , @Query("appkey") int appkey, @Query("sign") String sign, @Query("format") String format);



二、接口使用
private void doGet() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);
        Call<WeatherBeans> call = netService.requestWeather("weather.future", 1, 10003, "b59bc3ef6191eb9f747dd4e83c99f2a4","json");
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {

                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("temperature", bean.getDays() +"|"+bean.getTemperature());
                    }
                }
            }

            @Override
            public void onFailure(Call<WeatherBeans> call, Throwable t) {

            }
        });
    }


三、結果打印
09-08 18:40:42.951 16451-16451/hq.demo.net D/temperature: 2018-09-06|27℃/18℃
09-08 18:40:42.951 16451-16451/hq.demo.net D/temperature: 2018-09-07|27℃/16℃
09-08 18:40:42.951 16451-16451/hq.demo.net D/temperature: 2018-09-08|27℃/15℃
09-08 18:40:42.951 16451-16451/hq.demo.net D/temperature: 2018-09-09|28℃/17℃
09-08 18:40:42.951 16451-16451/hq.demo.net D/temperature: 2018-09-10|28℃/18℃
09-08 18:40:42.951 16451-16451/hq.demo.net D/temperature: 2018-09-11|27℃/18℃
09-08 18:40:42.951 16451-16451/hq.demo.net D/temperature: 2018-09-12|27℃/17℃

@QueryMap

一、接口定義


@GET("?")
Call<WeatherBeans> requestWeather(@QueryMap Map<String, String> paramas);


二、接口使用
private void doGet2() {
        Log.d("#####step", "#doGet2#");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);
        Map paramas = new HashMap<>();
        paramas.put("app","weather.future");
        paramas.put("weaid","1");
        paramas.put("appkey","10003");
        paramas.put("sign","b59bc3ef6191eb9f747dd4e83c99f2a4");
        paramas.put("format","json");

        Call<WeatherBeans> call = netService.requestWeather(paramas);
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {

                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("temperature", bean.getDays() +"|"+bean.getTemperature());
                    }
                }
            }

            @Override
            public void onFailure(Call<WeatherBeans> call, Throwable t) {

            }
        });
    }

三、結果打印:
09-08 19:16:43.669 18508-18508/hq.demo.net D/temperature: 2018-09-06|27℃/18℃
09-08 19:16:43.670 18508-18508/hq.demo.net D/temperature: 2018-09-07|27℃/16℃
09-08 19:16:43.670 18508-18508/hq.demo.net D/temperature: 2018-09-08|27℃/15℃
09-08 19:16:43.670 18508-18508/hq.demo.net D/temperature: 2018-09-09|28℃/17℃
09-08 19:16:43.670 18508-18508/hq.demo.net D/temperature: 2018-09-10|28℃/18℃
09-08 19:16:43.670 18508-18508/hq.demo.net D/temperature: 2018-09-11|27℃/18℃
09-08 19:16:43.670 18508-18508/hq.demo.net D/temperature: 2018-09-12|27℃/17℃

 

總結:@Query@QueryMap註解會把參數拼接到url後面,因此它適用於GET請求

 

@Url

下面使用到的實體類能夠經過GsonFormat插件生成,自行先訪問下面url,具體可參照:JSON轉實體類 好用插件 GsonFormat

一、接口定義
@GET
Call<Movies> requestMovies(@Url String url);

二、接口使用
public final static String requestUrl = "https://api.douban.com/v2/movie/top250?start=0&count=10";

    private void getRequestMovieList() {
        Log.d("---------->", "doGet0");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.douban.com/v2/movie/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);
        Call<Movies> call = netService.requestMovies(requestUrl);
        call.enqueue(new Callback<Movies>() {
            @Override
            public void onResponse(Call<Movies> call, Response<Movies> response) {
                if (response.isSuccessful()) {
                    Movies beans = response.body();
                    String title = beans.getTitle();
                    Log.d("##########title", "" + title);
                    List<Movies.Movie> movies = beans.getSubjects();
                    for (Movies.Movie movie : movies) {
                        String name = movie.getTitle();
                        Log.d("##########name", "" + name);
                    }
                }
            }

            @Override
            public void onFailure(Call<Movies> call, Throwable t) {

            }
        });
    }

三、結果打印
09-09 19:12:29.045 D/##########title: 豆瓣電影Top250
09-09 19:12:29.045 D/##########name: 肖申克的救贖
09-09 19:12:29.045 D/##########name: 霸王別姬
09-09 19:12:29.045 D/##########name: 這個殺手不太冷
09-09 19:12:29.045 D/##########name: 阿甘正傳
09-09 19:12:29.045 D/##########name: 美麗人生
09-09 19:12:29.045 D/##########name: 泰坦尼克號
09-09 19:12:29.045 D/##########name: 千與千尋
09-09 19:12:29.045 D/##########name: 辛德勒的名單
09-09 19:12:29.045 D/##########name: 盜夢空間
09-09 19:12:29.045 D/##########name: 機器人總動員

 

 

3.1.2 @POST

對應POST請求,不過須要結合@FormUrlEncoded來使用,

好比請求下面地址(這個地址是同時支持get、post請求的):

http://api.k780.com?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json

可使用post訪問,結合@Field或@FieldMap作表單提交

 

@Field

一、接口定義

@POST("/")
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeans(
            @Field("app") String app,
            @Field("weaid") String weaid,
            @Field("appkey") String appkey,
            @Field("sign") String sign,
            @Field("format") String format);


二、接口使用
private void doPost() {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);
        Call<WeatherBeans> call = netService.requestWeatherBeans("weather.future","1","10003","b59bc3ef6191eb9f747dd4e83c99f2a4","json");
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {


                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("weather:", bean.getCitynm() +"|"+bean.getDays()+"|"+bean.getTemperature());
                    }
                }
            }

            @Override
            public void onFailure(Call<WeatherBeans> call, Throwable t) {

            }
        });
    }

三、結果輸出:
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-06|27℃/18℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-07|27℃/16℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-08|27℃/15℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-09|28℃/17℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-10|28℃/18℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-11|27℃/18℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-12|27℃/17℃

 

@FieldMap

一、接口定義

@POST("/")
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeans(@FieldMap Map<String, String> fields);



二、接口使用
private void doPost1() {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);

        Map paramas = new HashMap<>();
        paramas.put("app","weather.future");
        paramas.put("weaid","1");
        paramas.put("appkey","10003");
        paramas.put("sign","b59bc3ef6191eb9f747dd4e83c99f2a4");
        paramas.put("format","json");

        Call<WeatherBeans> call = netService.requestWeatherBeans(paramas);
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {


                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("weather:", bean.getCitynm() +"|"+bean.getDays()+"|"+bean.getTemperature());
                    }
                }
            }

            @Override
            public void onFailure(Call<WeatherBeans> call, Throwable t) {

            }
        });
    }




三、結果輸出:
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-06|27℃/18℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-07|27℃/16℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-08|27℃/15℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-09|28℃/17℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-10|28℃/18℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-11|27℃/18℃
09-08 19:06:42.255 17872-17872/hq.demo.net D/weather:: 北京|2018-09-12|27℃/17℃

 

@Body

@Body會將請求參數放到請求體中,因此適用於POST請求

@Body標籤不能和@FormUrlEncoded或@Multipart標籤同時使用,會報錯

註釋源碼

翻譯:若是要直接控制POST / PUT請求的請求主體(而不是做爲請求參數或表單樣式請求主體發送),請在服務方法參數上使用此批註。該對象將使用Retrofit實例Converter進行序列化,結果將直接設置爲請求正文。

/**
 * Use this annotation on a service method param when you want to directly control the request body
 * of a POST/PUT request (instead of sending in as request parameters or form-style request
 * body). The object will be serialized using the {@link Retrofit Retrofit} instance
 * {@link Converter Converter} and the result will be set directly as the
 * request body.
 * <p>
 * Body parameters may not be {@code null}.
 */
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Body {
}

 

使用這個標籤的意思是咱們能夠定義個實體類來封裝參數,做爲請求參數,簡潔明瞭

@Body其實是將類轉換成json實體做爲請求體來請求網絡的,能夠抓包看

一、接口定義:
public interface NetService {


    @POST("/")
    Call<WeatherBeans> requestWeatherBeans(@Body RequestParams parama);


    class RequestParams {
        public String app;
        public int weaid;
        public int appkey;
        public String sign;
        public String format;
    }


}



二、接口使用
private void doPostWithBody() {
        Log.d("##########", "doPostWithBody");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);

        //建立以@Body註解post請求參數
        NetService.RequestParams params = new NetService.RequestParams();
        params.app = "weather.future";
        params.weaid = 1;
        params.appkey = 10003;
        params.sign = "b59bc3ef6191eb9f747dd4e83c99f2a4";
        params.format = "json";

        Call<WeatherBeans> call = netService.requestWeatherBeans(params);
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("weather:", bean.getCitynm() + "|" + bean.getDays() + "|" + bean.getTemperature());
                    }
                }
            }

            @Override
            public void onFailure(Call<WeatherBeans> call, Throwable t) {

            }
        });
    }

三、結果打印
因爲@Body其實是將類轉換成json實體做爲請求體來請求網絡,一時間沒找到能夠接受json格式的請求體做爲參數的網絡,所以這裏這是從形式說明怎麼使用,這是沒有問題,後面等我找到了能夠公開訪問的url地址再補上

 

常見錯誤1:@Body parameters cannot be used with form or multi-part encoding

注意:相比較前面的post請求去掉了@FormUrlEncoded註解,不然會報錯:

爲何會報錯,快捷鍵跟蹤一下@Body被使用的地方,在ServiceMethodlei中有源碼以下:

部分
else if (annotation instanceof Body) {
        if (isFormEncoded || isMultipart) {
          throw parameterError(p,
              "@Body parameters cannot be used with form or multi-part encoding.");
        }
        if (gotBody) {
          throw parameterError(p, "Multiple @Body method annotations found.");
        }

        Converter<?, RequestBody> converter;
        try {
          converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations);
        } catch (RuntimeException e) {
          // Wide exception range because factories are user code.
          throw parameterError(e, p, "Unable to create @Body converter for %s", type);
        }
        gotBody = true;
        return new ParameterHandler.Body<>(converter);
      }

常見錯誤2:@Unable to create @Body converter for %s

在遇到對請求參數或者請求結果加密處理的時候GsonConverterFactory可能沒法知足咱們的需求,所以須要重寫GsonConverterFactory,這時候須要重寫兩個方法以下,注意兩個方法必須同時重寫,不然可能就報這個錯誤

@Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter);
  }
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://api.k780.com")
        .addConverterFactory(GsonConverterFactory.create())
        .build();

 

2.1.3 @PUT

提交資源或者更新資源

將資源提交給服務器,若是請求的url地址已經在服務器上存在對應的資源了,則put請求提交的實體則會對其進行修改。

這裏就不舉例了

 

2.1.4 @DELETE

DELETE方法請求源服務器刪除Request-URI標識的資源。若是響應包括描述狀態的實體,則成功響應應爲200(OK),若是操做還沒有執行,則應爲202(已接受);若是操做已頒佈但響應不包括,則應爲204(無內容)一個實體。

DELETE方法與PUT相對應。

這裏就不舉例了

 

2.1.5 @PATCH

該請求是對PUT請求的補充,用於局部更新資源

這裏就不舉例了

 

2.1.6 @HEAD

        @HEAD用來表示http請求中的head請求,head請求來源是HTTP1.0,HTTP1.0有三種請求方式GET、POST、HEAD。HTTP1.1新增了PUT、DELETE、OPTIONS、 TRACE 、CONNECT。

 

        HEAD方法與GET相同,只是服務器不能在響應中返回消息體。響應HEAD請求的HTTP頭中包含的元信息應該與響應GET請求時發送的信息相同。該方法可用於得到關於請求所暗示的實體的元信息,而無需轉移實體主體自己。此方法一般用於測試超文本連接的有效性,可訪問性和最近的修改。

        對HEAD請求的響應是可緩存的,由於響應中包含的信息可用於從該資源更新先前緩存的實體。若是新字段值指示緩存的實體與當前實體不一樣(如Content-Length,Content-MD5,ETag或Last-Modified中的更改所示),則緩存必須將緩存條目視爲陳舊。

使用場景:

  • 檢查資源的有效性
  • 檢查超連接的有效性
  • 檢查網頁是否被串改
  • 用於自動搜索機器人獲取網頁的標誌信息,獲取rss種子信息,或者傳遞安全認證信息等
@Headers({"Content-Type: application/json", "Cache-Control: max-age=360000"})
Call<WeatherBeans> requestWeatherBeansByHeaders();

 

2.1.7 @OPTIONS

OPTIONS請求主要用途有兩個:

  • 獲取服務器支持的HTTP請求方法,是黑客喜歡使用的方法。
  • 用來檢查服務器的性能,如:AJAX進行跨域請求時的預檢,須要向另一個域名的資源發送一個HTTP OPTIONS請求頭,用以判斷實際發送的請求是否安全。

這裏就不舉例說明了

 

2.1.8 @HTTP

@HTTP請求,可配置成以上7種中的任意一種

@HTTP配置get請求

一、接口定義

@HTTP(method = "GET", path = "?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json", hasBody = false)
Call<WeatherBeans> requestWeatherBeansByHttp();


二、接口使用
private void doHttp() {
        Log.d("##########", "doHttp");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);


        Call<WeatherBeans> call = netService.requestWeatherBeansByHttp();
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("weather:", bean.getCitynm() + "|" + bean.getDays() + "|" + bean.getTemperature());
                    }
                }
            }

            @Override
            public void onFailure(Call<WeatherBeans> call, Throwable t) {

            }
        });
    }

三、結果打印
09-09 11:59:30.099 北京|2018-09-07|27℃/16℃
09-09 11:59:30.099 北京|2018-09-08|27℃/15℃
09-09 11:59:30.099 北京|2018-09-09|27℃/16℃
09-09 11:59:30.099 北京|2018-09-10|28℃/18℃
09-09 11:59:30.099 北京|2018-09-11|27℃/18℃
09-09 11:59:30.100 北京|2018-09-12|27℃/17℃
09-09 11:59:30.100 北京|2018-09-13|28℃/18℃

 

@HTTP配置post請求

注意:

1)配置POST請求必須結合@FormUrlEncoded使用,否者會報錯

2)hasBody必須配置爲true,不然報錯

java.lang.IllegalArgumentException: FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).

for method NetService.requestWeatherBeansByHttpPost

一、接口定義
@HTTP(method = "POST", path = "?", hasBody = true)
@FormUrlEncoded
Call<WeatherBeans> requestWeatherBeansByHttpPost(@FieldMap Map<String, String> paramas);

二、接口使用
private void doHttpPost() {
        Log.d("##########", "doHttpPost");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.k780.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);

        Map paramas = new HashMap<>();
        paramas.put("app", "weather.future");
        paramas.put("weaid", "1");
        paramas.put("appkey", "10003");
        paramas.put("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4");
        paramas.put("format", "json");

        Call<WeatherBeans> call = netService.requestWeatherBeansByHttpPost(paramas);
        call.enqueue(new Callback<WeatherBeans>() {
            @Override
            public void onResponse(Call<WeatherBeans> call, Response<WeatherBeans> response) {
                if (response.isSuccessful()) {
                    WeatherBeans beans = response.body();
                    for (WeatherBeans.ResultBean bean : beans.getResult()) {
                        Log.d("weather:", bean.getCitynm() + "|" + bean.getDays() + "|" + bean.getTemperature());
                    }
                }
            }

            @Override
            public void onFailure(Call<WeatherBeans> call, Throwable t) {

            }
        });
    }

三、結果打印
09-09 12:12:46.411 北京|2018-09-07|27℃/16℃
09-09 12:12:46.411 北京|2018-09-08|27℃/15℃
09-09 12:12:46.411 北京|2018-09-09|27℃/16℃
09-09 12:12:46.411 北京|2018-09-10|28℃/18℃
09-09 12:12:46.412 北京|2018-09-11|27℃/18℃

 

三、參數類註解

該類註解主要是結合上面8中註解使用,上面也都出現過部分,下面是總結

@Query、@QueryMap、@Url 、@Field、@FieldMap、@Body、@Headers 、@Header、@Part 、@PartMap 、@Path

public interface NetService {


    @GET("?")
    Call<WeatherBeans> requestWeather(@Query("app") String app, @Query("weaid") int weaid, @Query("appkey") int appkey, @Query("sign") String sign, @Query("format") String format);


    @GET("?")
    Call<WeatherBeans> requestWeather(@QueryMap Map<String, String> paramas);

    @GET
    Call<Movies> requestMovies(@Url String url);

    @POST("/")
    @FormUrlEncoded
    Call<WeatherBeans> requestWeatherBeans(
            @Field("app") String app,
            @Field("weaid") String weaid,
            @Field("appkey") String appkey,
            @Field("sign") String sign,
            @Field("format") String format);

    @POST("/")
    @FormUrlEncoded
    Call<WeatherBeans> requestWeatherBeans(@FieldMap Map<String, String> fields);



    @POST("/")
    Call<WeatherBeans> requestWeatherBeans(@Body RequestParams parama);


    class RequestParams {
        public String app;
        public int weaid;
        public int appkey;
        public String sign;
        public String format;
    }

    @Headers({"Content-Type: application/json", "Cache-Control: max-age=360000"})
    @HTTP(method = "GET", path = "?app=weather.future&weaid=1&&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json", hasBody = false)
    Call<WeatherBeans> requestWeatherBeansByHeaders();

    @GET("login")
    Call<UserInfo> login(@Header("Authorization") String authorization);

    @HTTP(method = "POST", path = "?", hasBody = true)
    @FormUrlEncoded
    Call<WeatherBeans> requestWeatherBeansByHttpPost(@FieldMap Map<String, String> paramas);


    @GET("back_pic/03/70/72/5257b6c12d89875.jpg!r850/fw/{id}")
    Call<ResponseBody> getImage(@Path("id") int id);

}

@Part

接口定義
    /**
     * 上傳圖文
     * @param description
     * @param file
     * @return
     */
    @Multipart
    @POST("web/shrink")
    Call<ResponseBody> uploadFile(@Part("description") RequestBody description, @Part MultipartBody.Part file);

    /**
     * 上傳一張圖片
     * @param file
     * @return
     */
    @Multipart
    @POST("web/shrink")
    Call<ResponseBody> uploadFile(@Part() RequestBody file);

    /**
     * 上傳一張圖片 另外一種寫法
     * @param file
     * @return
     */
    @Multipart
    @POST()
    Call<ResponseBody> uploadFile(@Url String url, @Part() RequestBody file);

    /**
     * 上傳數量肯定的多張圖片
     * @param description
     * @param img1
     * @param img2
     * @param img3
     * @return
     */
    @POST("web/shrink")
    Call<ResponseBody> uploadFiles(@Part("filename") String description,
                                   @Part("img\"; name=\"img1.png") RequestBody img1,
                                   @Part("img\"; name=\"img2.png") RequestBody img2,
                                   @Part("img\"; name=\"img3.png") RequestBody img3);

    /**
     * 上報數量不定的多張圖片 版本1
     * @param params
     * @return
     */
    @Multipart
    @POST("web/shrink")
    Call<ResponseBody> uploadFile(@PartMap Map<String, RequestBody> params);

    /**
     * 上報數量不定的多張圖片 版本2
     * @param url
     * @param maps
     * @return
     */
    @Multipart
    @POST()
    Call<ResponseBody> uploadFiles( @Url String url, @PartMap() Map<String, RequestBody> maps);



使用:
private void doUpload() {
        Log.d("---------->", "doUpload");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://tinypng.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);

        File file = getFile();
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        // MultipartBody.Part  和服務端約定好Key,這裏的part name是用image
        MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody);
        // 添加上傳文件描述
        String descriptionString = "文件描述:這是一張照片";
        RequestBody description = RequestBody.create(MediaType.parse("multipart/form-data"), descriptionString);

        Call<ResponseBody> call = netService.uploadFile(description, body);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful()) {
                    try {
                        ResponseBody responseBody = response.body();
                        Log.d("doUpload responseBody", responseBody.string());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                } else {
                    Log.d("doUpload responseBody", "failed");
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.d("doUpload responseBody", "onFailure");
            }
        });
    }

 

@Path

一、接口定義
@GET("back_pic/03/70/72/5257b6c12d89875.jpg!r850/fw/{id}")
Call<ResponseBody> getImage(@Path("id") int id);

二、接口使用
private void doGetImage() {
        Log.d("#####step", "#doGetImage#");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://bpic.588ku.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        NetService netService = retrofit.create(NetService.class);
        Call<ResponseBody> call = netService.getImage(800);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful()) {
                    Log.d("#####step", "#isSuccessful#");
                } else {
                    Log.d("#####step", "#Failure#");
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.d("#####step", "#onFailure#");
            }
        });
    }

三、結果打印
/#####step: #isSuccessful#

 

四、標記類

4.一、@FormUrlEncoded

主要是作表單提交,與@POST結合使用

4.二、@Multipart

主要是與@POST結合使用作文件的上傳

4.三、@Streaming

主要作大文件下載

@GET
@Streaming
Call<ResponseBody> downloadImage(@Url String url);
相關文章
相關標籤/搜索