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中添加依赖:html

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

1.2 安装插件

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

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

2 编程

2.1 Repository数据类

  • 在项目包中新建data class(装了前面那个插件才有);

  • 输入类的名字Repository,以及上述的json数据,点击OK建立好数据在Kotlin中的模型;

完成的Repository以下:github

//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...json

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

2.3 开始GET

分为3个步骤进行:api

  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文件,以下图。框架

总结

1 Retrofit

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

2 HTML

3 Kotlin

3.1 智能类型转换

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

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

3.2 扩展方法

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

3.3 rawString

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

相关文章
相关标签/搜索