Retrofit 2.x REST client教程

目錄:
1-- 關(guān)于Retrofit
2--前提
3--建立一個Retrofit客戶端
4--Retrofit 轉(zhuǎn)換器和適配器
5--Retrofit 授權(quán)
6--在Java中用Retrofit 去查詢Gerrit
7--用Retrofit 轉(zhuǎn)換從RSS得到到XML的響應(yīng)
8--做一個可以在StackOverflow搜索的程序
9--在Android中用Retrofit去訪問Github API

1. 關(guān)于Retrofit:

1.1 什么是Retfofit

Retrofit 是一個用來服務(wù)于Java和Android的REST 客戶端雄家。 用它可以非常容易的去接收和上傳json數(shù)據(jù)(或是其他數(shù)據(jù))坚嗜,通過一個建立在REST上面的web服務(wù)器。在Retrofit中可以配置轉(zhuǎn)換器來進行數(shù)據(jù)序列化蜻势。特別是用GSon來轉(zhuǎn)換json數(shù)據(jù),同時一個你也定制你的轉(zhuǎn)換器丸逸,別入來進行解析XML數(shù)據(jù)或是其他相關(guān)協(xié)議的數(shù)據(jù)超陆。Retrofit的HTTP 請求部分用的是OkHttp 庫

1.2 Retrofit的用法:

一般情況下蟀俊,你會跟Retrofit的三個類打交道:
  • JSON 模塊
  • 定義一個接口,在接口里面做跟HTTP相關(guān)的操作
  • Retrofit.Builder Class 订雾,它的實例接口和其相關(guān)的API可以允許你去定義用URL只想的HTTP操作

接口中的每個方法代表一個API調(diào)用肢预。他們必須有一個HTTP注解(GET,POST等)去指定一個請求類型和相關(guān)的URL.返回的值包裝了一個response 結(jié)果(如果不清楚注解,請參考我的博文

@GET("users")
Call<List<User>> getUsers();

你可以用"替換塊"和查詢參數(shù)去調(diào)整你的URL.替換塊必須由{}來包裹洼哎。在函數(shù)參數(shù)中的@Path的值會和你指定的替換塊綁定到一起烫映。

@GET("users/{name}/commits")//{name}即使替換塊
Call<List<Commit>> getCommitsByName(@Path("name") String name);

查詢參數(shù)在函數(shù)參數(shù)中用注解@Query來進行包裝沼本,他們會自動的被添加到URL的末端。

@GET("users")
Call<User> getUserById(@Query("id") Integer id);

函數(shù)參數(shù)中的@Body注解來告訴Retrofit窑邦,用這個對象來作為請求體(注意HTTP的三部分:請求頭擅威,請求行,請求體)

@POST("users")

Call<User> postUser(@Body User user)//這里冈钦,User的對象user就是請求體

2. 前提

以下例子需要你了解Gradle build 系統(tǒng)或是在Eclipse中使用Gradle,當(dāng)然你在Visual Studio中用Gradle那也沒有啥錯李请。

3. 建立一個Retrofit客戶端(小例子)

在這個例子中你會知道如何創(chuàng)建一個標準的REST 客戶端瞧筛。我們接收Resopose的服務(wù)器為mock server。

3.1 創(chuàng)建項目并設(shè)置

增加遠程依賴导盅,創(chuàng)建一個新的Project较幌,名字是com.vogella.retrofitgerrit. 并在src/main/java下創(chuàng)建一個名字為com.vogella.retrofitgerrit的包.

// retrofit
//Android studio setup--最新版本
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
// Junit
testImplementation("org.junit.jupiter:junit-jupiter-api:5.0.0")
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0")
// to run JUnit 3/4 tests:
testImplementation("junit:junit:4.12")
testRuntime("org.junit.vintage:junit-vintage-engine:4.12.0")

3.2 定義API和Retrofit適配器:

從Gerrit收到的JSON回復(fù),我們僅僅需要關(guān)注它的主題變化白翻,因此在默認的包中建立如下類:

package com.vogella.java.retrofitgerrit;

public class Change {
    String subject;

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }
}

在以下接口中定義Retrofit的REST API:

package com.vogella.java.retrofitgerrit;

import java.util.List;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface GerritAPI {

    @GET("changes/")
    Call<List<Change>> loadChanges(@Query("q") String status);
}

創(chuàng)建一個controller控制器類乍炉,這個類創(chuàng)造了Retrofit client, 調(diào)用Gerrit API以及處理結(jié)果(打印調(diào)用后返回的結(jié)果到console)

package com.vogella.java.retrofitgerrit;

import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class Controller implements Callback<List<Change>> {

    static final String BASE_URL = "https://git.eclipse.org/r/";

    public void start() {
        Gson gson = new GsonBuilder()
                .setLenient()
                .create();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .build();

        GerritAPI gerritAPI = retrofit.create(GerritAPI.class);

        Call<List<Change>> call = gerritAPI.loadChanges("status:open");
        call.enqueue(this);

    }

    @Override
    public void onResponse(Call<List<Change>> call, Response<List<Change>> response) {
        if(response.isSuccessful()) {
            List<Change> changesList = response.body();
            changesList.forEach(change -> System.out.println(change.subject));
        } else {
            System.out.println(response.errorBody());
        }
    }

    @Override
    public void onFailure(Call<List<Change>> call, Throwable t) {
        t.printStackTrace();
    }
}

創(chuàng)建一個包含Java程序入口的類滤馍,從而啟動這個控制器類

package com.vogella.java.retrofitgerrit;
public class Main {

    public static void main(String[] args) {
        Controller controller = new Controller();
        controller.start();
    }
}

4.Retrofit 轉(zhuǎn)換器和適

4.1 Retrofit 轉(zhuǎn)換器

Retrofit 可以配置一個特殊的轉(zhuǎn)換器岛琼。用這個轉(zhuǎn)換器來處理數(shù)據(jù)序列化。目前幾個轉(zhuǎn)換器已經(jīng)可以使用于數(shù)據(jù)序列化巢株。

  • 從JSON轉(zhuǎn)換
    Gson:com.squareup.retrofit:converter-gson
    Jackson:com.squareup.retrofit:converter-jackson
    Moshi:com.squareup.retrofit:converter-moshi
    除了上面列出的槐瑞,當(dāng)然你自己也可以通過Converter.Factory類的子集來定制自己的轉(zhuǎn)換器,通過特殊的協(xié)議阁苞。

4.2 Retrofit 適配器

Retrofit本身也可以被繼承困檩,從而去和一些其他的庫(RxJava2.x,Java8那槽,Guava)一起協(xié)同工作(這點很重要悼沿,例如okHttp就不太適合去和RxJava去協(xié)同工作,這也是為什么既然選擇okHttp就不如直接用Retrofit的一個原因)
關(guān)于適配器的一個概述骚灸,請參考Adaptersquare/retrofit/retrofit-adapters/.
例如糟趾,RxJava 2.下 adapter 可以從Gradle獲得:
compile 'com.squareup.retrofit2:adapter-rxjava2:latest.version'
用Apache的遠程倉庫Maven:

<dependency>
 <groupId>com.squareup.retrofit2</groupId>
 <artifactId>adapter-rxjava2</artifactId>
 <version>latest.version</version>
</dependency>

如果你要添加一個適配器(Adapter),那么要用到以下這個方法
retrofit2.Retrofit.Builder.addCallAdapterFactory(Factory)

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.example.com")
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加適配器
    .build()

再Retrofit添加這個適配器后就會返回一個RxJava2.x 的一個類型逢唤。Observable拉讯,F(xiàn)lowable和Single 等等。

@GET("users")
Observable<List<User>> getUsers();

Retrofit 授權(quán)


回頭完善內(nèi)容多...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鳖藕,一起剝皮案震驚了整個濱河市魔慷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌著恩,老刑警劉巖院尔,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蜻展,死亡現(xiàn)場離奇詭異,居然都是意外死亡邀摆,警方通過查閱死者的電腦和手機纵顾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栋盹,“玉大人施逾,你說我怎么就攤上這事±瘢” “怎么了汉额?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長榨汤。 經(jīng)常有香客問我蠕搜,道長,這世上最難降的妖魔是什么收壕? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任妓灌,我火速辦了婚禮,結(jié)果婚禮上蜜宪,老公的妹妹穿的比我還像新娘虫埂。我一直安慰自己,他們只是感情好端壳,可當(dāng)我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布告丢。 她就那樣靜靜地躺著,像睡著了一般损谦。 火紅的嫁衣襯著肌膚如雪岖免。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天照捡,我揣著相機與錄音挣磨,去河邊找鬼黎侈。 笑死沿后,一個胖子當(dāng)著我的面吹牛彪蓬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播悲立,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼鹿寨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了薪夕?” 一聲冷哼從身側(cè)響起脚草,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎原献,沒想到半個月后馏慨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體埂淮,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年写隶,在試婚紗的時候發(fā)現(xiàn)自己被綠了倔撞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡慕趴,死狀恐怖痪蝇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冕房,我是刑警寧澤霹俺,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站毒费,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏愈魏。R本人自食惡果不足惜觅玻,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望培漏。 院中可真熱鬧溪厘,春花似錦、人聲如沸牌柄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽珊佣。三九已至蹋宦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咒锻,已是汗流浹背冷冗。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惑艇,地道東北人蒿辙。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像滨巴,于是被迫代替她去往敵國和親思灌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,926評論 2 361

推薦閱讀更多精彩內(nèi)容