转载

Java转Kotlin:使用Retrofit进行网络请求

  • 案例目标
  1. 在Kotlin中使用Java第三方框架;
  2. 加深对Kotlin类型的认识。
  • 案例效果
  1. 使用 api.github.com/repos/Jetbr… 接口获取Kotlin开源仓库的基本信息:在浏览器或者 POSTMAN 软件获得上述请求返回的json数据如下:
{
    "id": 3432266,
    "node_id": "MDEwOlJlcG9zaXRvcnkzNDMyMjY2",
    "name": "kotlin",
    "full_name": "JetBrains/kotlin",
    "private": false,
    "owner": {
        "login": "JetBrains",
        "id": 878437,
        "node_id": "MDEyOk9yZ2FuaXphdGlvbjg3ODQzNw==",
        "avatar_url": "https://avatars2.githubusercontent.com/u/878437?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/JetBrains",
        "html_url": "https://github.com/JetBrains",
        "followers_url": "https://api.github.com/users/JetBrains/followers",
        "following_url": "https://api.github.com/users/JetBrains/following{/other_user}",
        "gists_url": "https://api.github.com/users/JetBrains/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/JetBrains/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/JetBrains/subscriptions",
        "organizations_url": "https://api.github.com/users/JetBrains/orgs",
        "repos_url": "https://api.github.com/users/JetBrains/repos",
        "events_url": "https://api.github.com/users/JetBrains/events{/privacy}",
        "received_events_url": "https://api.github.com/users/JetBrains/received_events",
        "type": "Organization",
        "site_admin": false
    },
    "html_url": "https://github.com/JetBrains/kotlin",
    "description": "The Kotlin Programming Language",
    "fork": false,
    "url": "https://api.github.com/repos/JetBrains/kotlin",
    "forks_url": "https://api.github.com/repos/JetBrains/kotlin/forks",
    "keys_url": "https://api.github.com/repos/JetBrains/kotlin/keys{/key_id}",
    "collaborators_url": "https://api.github.com/repos/JetBrains/kotlin/collaborators{/collaborator}",
    "teams_url": "https://api.github.com/repos/JetBrains/kotlin/teams",
    "hooks_url": "https://api.github.com/repos/JetBrains/kotlin/hooks",
    "issue_events_url": "https://api.github.com/repos/JetBrains/kotlin/issues/events{/number}",
    "events_url": "https://api.github.com/repos/JetBrains/kotlin/events",
    "assignees_url": "https://api.github.com/repos/JetBrains/kotlin/assignees{/user}",
    "branches_url": "https://api.github.com/repos/JetBrains/kotlin/branches{/branch}",
    "tags_url": "https://api.github.com/repos/JetBrains/kotlin/tags",
    "blobs_url": "https://api.github.com/repos/JetBrains/kotlin/git/blobs{/sha}",
    "git_tags_url": "https://api.github.com/repos/JetBrains/kotlin/git/tags{/sha}",
    "git_refs_url": "https://api.github.com/repos/JetBrains/kotlin/git/refs{/sha}",
    "trees_url": "https://api.github.com/repos/JetBrains/kotlin/git/trees{/sha}",
    "statuses_url": "https://api.github.com/repos/JetBrains/kotlin/statuses/{sha}",
    "languages_url": "https://api.github.com/repos/JetBrains/kotlin/languages",
    "stargazers_url": "https://api.github.com/repos/JetBrains/kotlin/stargazers",
    "contributors_url": "https://api.github.com/repos/JetBrains/kotlin/contributors",
    "subscribers_url": "https://api.github.com/repos/JetBrains/kotlin/subscribers",
    "subscription_url": "https://api.github.com/repos/JetBrains/kotlin/subscription",
    "commits_url": "https://api.github.com/repos/JetBrains/kotlin/commits{/sha}",
    "git_commits_url": "https://api.github.com/repos/JetBrains/kotlin/git/commits{/sha}",
    "comments_url": "https://api.github.com/repos/JetBrains/kotlin/comments{/number}",
    "issue_comment_url": "https://api.github.com/repos/JetBrains/kotlin/issues/comments{/number}",
    "contents_url": "https://api.github.com/repos/JetBrains/kotlin/contents/{+path}",
    "compare_url": "https://api.github.com/repos/JetBrains/kotlin/compare/{base}...{head}",
    "merges_url": "https://api.github.com/repos/JetBrains/kotlin/merges",
    "archive_url": "https://api.github.com/repos/JetBrains/kotlin/{archive_format}{/ref}",
    "downloads_url": "https://api.github.com/repos/JetBrains/kotlin/downloads",
    "issues_url": "https://api.github.com/repos/JetBrains/kotlin/issues{/number}",
    "pulls_url": "https://api.github.com/repos/JetBrains/kotlin/pulls{/number}",
    "milestones_url": "https://api.github.com/repos/JetBrains/kotlin/milestones{/number}",
    "notifications_url": "https://api.github.com/repos/JetBrains/kotlin/notifications{?since,all,participating}",
    "labels_url": "https://api.github.com/repos/JetBrains/kotlin/labels{/name}",
    "releases_url": "https://api.github.com/repos/JetBrains/kotlin/releases{/id}",
    "deployments_url": "https://api.github.com/repos/JetBrains/kotlin/deployments",
    "created_at": "2012-02-13T17:29:58Z",
    "updated_at": "2020-04-11T06:41:21Z",
    "pushed_at": "2020-04-11T07:33:43Z",
    "git_url": "git://github.com/JetBrains/kotlin.git",
    "ssh_url": "git@github.com:JetBrains/kotlin.git",
    "clone_url": "https://github.com/JetBrains/kotlin.git",
    "svn_url": "https://github.com/JetBrains/kotlin",
    "homepage": "https://kotlinlang.org/",
    "size": 684759,
    "stargazers_count": 31302,
    "watchers_count": 31302,
    "language": "Kotlin",
    "has_issues": false,
    "has_projects": false,
    "has_downloads": true,
    "has_wiki": false,
    "has_pages": true,
    "forks_count": 3815,
    "mirror_url": null,
    "archived": false,
    "disabled": false,
    "open_issues_count": 212,
    "license": null,
    "forks": 3815,
    "open_issues": 212,
    "watchers": 31302,
    "default_branch": "master",
    "temp_clone_token": null,
    "organization": {
        "login": "JetBrains",
        "id": 878437,
        "node_id": "MDEyOk9yZ2FuaXphdGlvbjg3ODQzNw==",
        "avatar_url": "https://avatars2.githubusercontent.com/u/878437?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/JetBrains",
        "html_url": "https://github.com/JetBrains",
        "followers_url": "https://api.github.com/users/JetBrains/followers",
        "following_url": "https://api.github.com/users/JetBrains/following{/other_user}",
        "gists_url": "https://api.github.com/users/JetBrains/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/JetBrains/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/JetBrains/subscriptions",
        "organizations_url": "https://api.github.com/users/JetBrains/orgs",
        "repos_url": "https://api.github.com/users/JetBrains/repos",
        "events_url": "https://api.github.com/users/JetBrains/events{/privacy}",
        "received_events_url": "https://api.github.com/users/JetBrains/received_events",
        "type": "Organization",
        "site_admin": false
    },
    "network_count": 3815,
    "subscribers_count": 1257
}
复制代码
  1. 将获取到的基本信息输出成一个HTML文件。

开始

1 准备

1.1 添加依赖

在项目的build.gradle中添加依赖:

implementation "com.squareup.retrofit2:retrofit:2.6.2"
implementation "com.squareup.retrofit2:converter-gson:2.6.2"
implementation "com.google.code.gson:gson:2.8.1"
复制代码

如图

Java转Kotlin:使用Retrofit进行网络请求

1.2 安装插件

安装IntelliJ平台插件 NewDataClassAction (by bennyhuo)

用于将Json数据转换成Kotlin中的 data class

2 编程

2.1 Repository数据类

  • 在项目包中新建 data class (装了前面那个插件才有);
Java转Kotlin:使用Retrofit进行网络请求
  • 输入类的名字 Repository ,以及上述的json数据,点击OK创建好数据在Kotlin中的模型;
Java转Kotlin:使用Retrofit进行网络请求

完成的 Repository 如下:

//Kotlin
package imooc.chapter_4.try_retrofit

/**
 * Created by tongbo on 2020-04-11
 */
data class Repository(
    var id: Int,
    var node_id: String,
    var name: String,
    var full_name: String,
    var private: Boolean,
    var owner: Owner,
    var html_url: String,
    var description: String,
    var fork: Boolean,
    var url: String,
    var forks_url: String,
    var keys_url: String,
    var collaborators_url: String,
    var teams_url: String,
    var hooks_url: String,
    var issue_events_url: String,
    var events_url: String,
    var assignees_url: String,
    var branches_url: String,
    var tags_url: String,
    var blobs_url: String,
    var git_tags_url: String,
    var git_refs_url: String,
    var trees_url: String,
    var statuses_url: String,
    var languages_url: String,
    var stargazers_url: String,
    var contributors_url: String,
    var subscribers_url: String,
    var subscription_url: String,
    var commits_url: String,
    var git_commits_url: String,
    var comments_url: String,
    var issue_comment_url: String,
    var contents_url: String,
    var compare_url: String,
    var merges_url: String,
    var archive_url: String,
    var downloads_url: String,
    var issues_url: String,
    var pulls_url: String,
    var milestones_url: String,
    var notifications_url: String,
    var labels_url: String,
    var releases_url: String,
    var deployments_url: String,
    var created_at: String,
    var updated_at: String,
    var pushed_at: String,
    var git_url: String,
    var ssh_url: String,
    var clone_url: String,
    var svn_url: String,
    var homepage: String,
    var size: Int,
    var stargazers_count: Int,
    var watchers_count: Int,
    var language: String,
    var has_issues: Boolean,
    var has_projects: Boolean,
    var has_downloads: Boolean,
    var has_wiki: Boolean,
    var has_pages: Boolean,
    var forks_count: Int,
    var mirror_url: Any,
    var archived: Boolean,
    var disabled: Boolean,
    var open_issues_count: Int,
    var license: Any,
    var forks: Int,
    var open_issues: Int,
    var watchers: Int,
    var default_branch: String,
    var temp_clone_token: Any,
    var organization: Organization,
    var network_count: Int,
    var subscribers_count: Int
) {
    data class Owner(
        var login: String,
        var id: Int,
        var node_id: String,
        var avatar_url: String,
        var gravatar_id: String,
        var url: String,
        var html_url: String,
        var followers_url: String,
        var following_url: String,
        var gists_url: String,
        var starred_url: String,
        var subscriptions_url: String,
        var organizations_url: String,
        var repos_url: String,
        var events_url: String,
        var received_events_url: String,
        var type: String,
        var site_admin: Boolean
    )

    data class Organization(
        var login: String,
        var id: Int,
        var node_id: String,
        var avatar_url: String,
        var gravatar_id: String,
        var url: String,
        var html_url: String,
        var followers_url: String,
        var following_url: String,
        var gists_url: String,
        var starred_url: String,
        var subscriptions_url: String,
        var organizations_url: String,
        var repos_url: String,
        var events_url: String,
        var received_events_url: String,
        var type: String,
        var site_admin: Boolean
    )
}
复制代码

2.2 GithubApi接口

定义一个接口 GithubApi ,在接口中定义一个 getRepository 函数(方法)传入参数 ownerrepo ,返回一个 Repository

Retrofit blah blah blah...

//Kotlin
interface GithubApi {
    @GET("/repos/{owner}/{repo}")
    fun getRepository(@Path("owner") owner: String, @Path("repo") repo: String): Call<Repository>
}
复制代码

2.3 开始GET

分为3个步骤进行:

  1. 利用 Retrofit 创建 githubApi 接口实例;
  2. 执行获取,获得 response
  3. response 内容进行处理,例如写入HTML文件。

编辑 main() 函数:

//Kotlin
fun main() {
    val githubApi = Retrofit.Builder().baseUrl("https://api.github.com")
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(GithubApi::class.java)
    val response = githubApi.getRepository("Jetbrains", "Kotlin").execute()
    val repository = response.body()
    if (repository == null) {
        println("Error! ${response.code()} : ${response.message()}")
    } else {
        //TODO:将信息写入HTML文件
        File("src//main//kotlin//imooc//chapter_4//try_retrofit//KotlinRepoInfo.html").writeText(
            """
            <!DOCTYPE html>
            <html>
              <head>
                <meta charset="utf-8">
                <title>${repository.owner.login} - ${repository.name}</title>
              </head>
              <body>
                <h1><a href='${repository.html_url}'>${repository.owner.login} - ${repository.name}</a></h1>
                <p>${repository.description}</p>
                <p>Stars : ${repository.stargazers_count}</p>
                <p>Folks : ${repository.forks_count}</p>
              </body>
            </html>
        """.trimIndent()
        )
    }
}
复制代码

浏览器查看 src//main//kotlin//imooc//chapter_4//try_retrofit//KotlinRepoInfo.html 文件,如下图。

Java转Kotlin:使用Retrofit进行网络请求

总结

1 Retrofit

关于 Retrofit 的知识点,推荐大家bennyhuo的免费课程 《破解Retrofit》

2 HTML

3 Kotlin

3.1 智能类型转换

在判断 repository == null 前, repository 变量的类型是可空的 Repository? :

Java转Kotlin:使用Retrofit进行网络请求

在判断 repository == null 后,编译器进行了智能类型转换,变成非空的 Repository 类型:

Java转Kotlin:使用Retrofit进行网络请求

3.2 扩展方法

在使用Java Api的 File 时,我们使用了 writeText() 方法,该方法是Kotlin的扩展方法:

Java转Kotlin:使用Retrofit进行网络请求

3.3 rawString

写入HTML文件时,我们使用了rawString,及其方法 trimIndent() ,该方法帮助删除rawString中的 公共缩进

Java转Kotlin:使用Retrofit进行网络请求
原文  https://juejin.im/post/5e91663ee51d4546f03d953c
正文到此结束
Loading...