ReactiveX 学习笔记(14)使用 RxJava2 + Retrofit2 调用 REST API
JSON : Placeholder
JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站。
以下使用 RxJava2 + Retrofit2 调用该网站的 REST API,获取字符串以及 JSON 数据。
- GET /posts/1
- GET /posts
- POST /posts
- PUT /posts/1
- DELETE /posts/1
所有 GET API 都返回JSON数据,格式(JSON-Schema)如下:
{
"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 按钮创建工程
build.gradle 内容如下
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 这部分的内容改为:
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 和字符串的转换器。
Post 对象
jsonschema2pojo 可以将 JSON 数据或格式自动转换为 Java 的 POJO 类。
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) {
// ...
}
Retrofit 接口
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。
- 接口中的每一个方法都对应于一种 API 调用。
- 注解 @GET @POST @PUT @DELETE 表示 API 调用时所使用的 HTTP 方法。
- 注解 @GET 中带的值表示 API 调用时所包含的相对路径,其中可包含路径变量。
"posts/{id}" 中的 {id} 为路径变量。 - 注解 @Url 表示参数为路径。
- 注解 @Path("id") 表示参数为路径变量。
- 注解 @Field 表示参数为 HTTP 请求体中的键值对。
- 使用注解 @Field 的方法必须加上注解 @FormUrlEncoded。
Retrofit 对象
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()
- retrofitJson 对象用于处理 REST API 所返回的 JSON 数据。
- retrofitString 对象用于处理 REST API 所返回的字符串数据。
调用 REST API
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)
- getPostAsString 函数取出第1个Post,返回字符串
- getPostAsJson 函数取出第1个Post,返回Post对象
- getPosts 函数取出前n个Post,返回n个Post对象
- createPost 函数创建1个Post,返回所创建的Post对象
- updatePost 函数更新第1个Post,返回所更新的Post对象
- deletePost 函数删除第1个Post,返回字符串
main 函数
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"}
{}
ReactiveX 学习笔记(14)使用 RxJava2 + Retrofit2 调用 REST API的更多相关文章
- ReactiveX 学习笔记(0)学习资源
ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...
- mybatis学习笔记(14)-查询缓存之中的一个级缓存
mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...
- 并发编程学习笔记(14)----ThreadPoolExecutor(线程池)的使用及原理
1. 概述 1.1 什么是线程池 与jdbc连接池类似,在创建线程池或销毁线程时,会消耗大量的系统资源,因此在java中提出了线程池的概念,预先创建好固定数量的线程,当有任务需要线程去执行时,不用再去 ...
- 【转】 C#学习笔记14——Trace、Debug和TraceSource的使用以及日志设计
[转] C#学习笔记14——Trace.Debug和TraceSource的使用以及日志设计 Trace.Debug和TraceSource的使用以及日志设计 .NET Framework 命名空 ...
- [C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good
[C++学习笔记14]动态创建对象 C#/Java中的反射机制 动态获取类型信息(方法与属性) 动态创建对象 动态调用对象的方法 动态操作对象的属性 前提:需要给每个类添加元数据 动态创建对象 实 ...
- Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法
Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法 Ext.Net GridPanel可以进行Group操作,例如: 如何启用Grouping功能呢?只需要在Grid ...
- Memcached 学习笔记(二)——ruby调用
Memcached 学习笔记(二)——ruby调用 上一节我们讲述了怎样安装memcached及memcached常用命令.这一节我们将通过ruby来调用memcached相关操作. 第一步,安装ru ...
- SQL反模式学习笔记14 关于Null值的使用
目标:辨别并使用Null值 反模式:将Null值作为普通的值,反之亦然 1.在表达式中使用Null: Null值与空字符串是不一样的,Null值参与任何的加.减.乘.除等其他运算,结果都是Null: ...
- golang学习笔记14 golang substring 截取字符串
golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...
随机推荐
- [UE4]AWP开镜时模糊
一.Add to Viewport的Zorder越大,添加进来的UI越靠近前面.也就是大的Zorder会覆盖Zorder小的UI. 二.镜头模糊,在专心UI中添加一个模糊滤镜设置模糊值,并放在最上层.
- [UE4]背景模糊
被遮挡的都会被模糊,没被遮挡的不会模糊
- 总结一下连日来在MAC下被Python3设下的坑
当时的情况:mac下自带python2, 1.安装pyhon3: 首次从官网下载了安装包安装,安装目录在/Library/Frameworks/Python.framework/Versions/3. ...
- Sharing Configuration in ASP.NET Core SPA Scenarios
https://blogs.msdn.microsoft.com/webdev/2017/10/27/sharing-configuration-in-asp-net-core-spa-scenari ...
- Servlet基础学习
Servlet学习 Servlet是Server与Applet的缩写,是服务端小程序的意思.使用Java语言编写的服务器端程序,可以像生成动态的WEB页,Servlet主要运行在服务器端,并由服务器调 ...
- mysql sql中的一些问题,Null与空字符
mysql中的空值,NULL,空字符 Mysql数据库是一个基于结构化数据的开源数据库.SQL语句是MySQL数据库中核心语言.不过在MySQL数据库中执行SQL语句,需要小心两个陷阱. 陷阱一:空值 ...
- 求计算两个时间的差(DateTime类和TimeSpan类)
日期时间数据是项目设计过程中经常需要处理的信息,C#提供了DateTime类和TimeSpan类来处理日期时间数据.下面介绍说明Datetime类和TimeSpan类的使用 //初始化DateTime ...
- Win10还原被Windows Defender隔离的文件
Win10最新版本的Windows Defender隔离/删除的文件没有还原的选项,导致很多破解文件或是注册机直接隔离,到威胁历史记录中去却无法恢复.经过各个尝试,到微软官方论坛中也尝试了很多方法,后 ...
- switch嵌套--猜拳游戏
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- idea error:Command line is too long
今天在正在本地运行的项目中写了一个无关项目的测试类,执行main函数时报错如下: 解决方案: 找到项目根目录下的.idea/workspace.xml,添加内容: <component name ...