JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一個用於測試的 REST API 網站。
如下使用 RxJava2 + Retrofit2 調用該網站的 REST API,獲取字符串以及 JSON 數據。java
全部 GET API 都返回JSON數據,格式(JSON-Schema)以下:react
{ "type":"object", "properties": { "userId": {"type" : "integer"}, "id": {"type" : "integer"}, "title": {"type" : "string"}, "body": {"type" : "string"} } }
打開 Intellij IDEA,File / New / Project...
在 New Project 嚮導的第1頁,選 Gradle,Project SDK 選 1.8,Additional Libraries and Frameworks 選 Java + Kotlin(Java)。
在嚮導的第2頁填上 ArtifactId
在嚮導的第3頁選中 use auto-import
在嚮導的第4頁點擊 Finish 按鈕建立工程json
build.gradle 內容以下api
plugins { id 'java' id 'org.jetbrains.kotlin.jvm' version '1.2.60' } version '1.0-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8" testCompile group: 'junit', name: 'junit', version: '4.12' } compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" }
將 dependencies 這部分的內容改成:jvm
def retrofit_version = '2.4.0' dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" testImplementation group: 'junit', name: 'junit', version: '4.12' implementation 'io.reactivex.rxjava2:rxjava:2.1.16' implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0' implementation "com.squareup.retrofit2:retrofit:$retrofit_version" implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofit_version" implementation "com.squareup.retrofit2:converter-gson:$retrofit_version" implementation "com.squareup.retrofit2:converter-scalars:$retrofit_version" }
這一段一共引用了 RxJava, RxKotlin, Retrofit 3個庫。
其中 Retrofit 這個庫中還包含了 RxJava 的適配器,以及 Gson 和字符串的轉換器。maven
jsonschema2pojo 能夠將 JSON 數據或格式自動轉換爲 Java 的 POJO 類。ide
data class Post(val userId: Int, val id: Int, val title: String, val body: String) { override fun toString() = "Post {userId = $userId, id = $id, title = \"$title\", body = \"${body.replace("\n", "\\n")}\"}" }
Post 對象負責 Kotlin 對象與 JSON 數據之間的相互轉換。
因爲二者字段名相同,這裏不須要使用註解。函數
// 若是須要加上註解的話 data class Post(@SerializedName("userId") @Expose val userId: Int, @SerializedName("id") @Expose val id: Int, @SerializedName("title") @Expose val title: String, @SerializedName("body") @Expose val body: String) { // ... }
interface RestPost { @GET fun getPostAsString(@Url url: String): Observable<String> @GET("posts/{id}") fun getPostAsJson(@Path("id") id: Int): Observable<Post> @GET("posts") fun getPosts(): Observable<List<Post>> @FormUrlEncoded @POST("posts") fun createPost(@Field("userId") userId: Int, @Field("title") title: String, @Field("body") body: String): Observable<Post> @FormUrlEncoded @PUT("posts/{id}") fun updatePost(@Field("userId") userId: Int, @Path("id") id: Int, @Field("title") title: String, @Field("body") body: String): Observable<Post> @DELETE("posts/{id}") fun deletePost(@Path("id") id: Int): Observable<String> }
Retrofit 庫使用專用接口調用 REST API。post
val retrofitJson: Retrofit = Retrofit.Builder() .baseUrl("https://jsonplaceholder.typicode.com/") .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build() val retrofitString: Retrofit = Retrofit.Builder() .baseUrl("https://jsonplaceholder.typicode.com/") .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create()) .build()
fun getPostAsString(): Observable<String> = retrofitString.create(RestPost::class.java) .getPostAsString("posts/1") fun getPostAsJson(): Observable<Post> = retrofitJson.create(RestPost::class.java) .getPostAsJson(1) fun getPosts(n: Long): Observable<Post> = retrofitJson.create(RestPost::class.java) .getPosts().flatMapIterable { x -> x }.take(n) fun createPost(): Observable<Post> = retrofitJson.create(RestPost::class.java) .createPost(101, "test title", "test body") fun updatePost(): Observable<Post> = retrofitJson.create(RestPost::class.java) .updatePost(101, 1, "test title", "test body") fun deletePost(): Observable<String> = retrofitString.create(RestPost::class.java) .deletePost(1)
fun main(args: Array<String>) { getPostAsString().subscribe(::println) getPostAsJson().subscribe(::println) getPosts(2).subscribe(::println) createPost().subscribe(::println) updatePost().subscribe(::println) deletePost().subscribe(::println) }
{ "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" } Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"} Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"} Post {userId = 1, id = 2, title = "qui est esse", body = "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"} Post {userId = 101, id = 101, title = "test title", body = "test body"} Post {userId = 101, id = 1, title = "test title", body = "test body"} {}