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中的公共縮進

相關文章
相關標籤/搜索