在 Kotlin 中创建 HTTP 请求
HTTP 是一种网络通信协议,负责从网络服务器向网络浏览器提供网络内容。
Web 内容可能是静态数据或动态数据。 静态数据是指页面上显示的信息不会改变,而动态数据显示在网页上是一直在变化的。
从服务器检索的数据包括结构化数据、图像和视频文件。 大多数应用程序通常使用由数据库管理的结构化数据。
从数据库获取数据到 Web 客户端的一种常见方法是使用 RESTful API。 RESTful API 由应用程序通过 HTTP 协议使用不同的库来消费,并加载到 Web 客户端。
在本篇文章中,我们将学习可用于创建使用 Restful API 的 HTTP 请求的不同方法。 Restful API 从 Heroku 上托管的应用程序返回国家列表。
创建 Kotlin 项目并添加依赖项
打开 IntelliJ 开发环境并选择文件 > 新建 > 项目。 在打开的窗口中,输入项目名称 kotlin-http-request,在 Language 部分选择 Kotlin,在 Build system 部分选择 Gradle。
最后,按创建按钮生成项目。
打开文件 build.gradle.kts 并确保您拥有以下代码中显示的所有依赖项。 这些依赖项帮助我们添加可用于创建 HTTP 请求的库。
dependencies{
implementation ("com.squareup.retrofit2:retrofit:2.9.0")
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
implementation ("com.github.kittinunf.fuel:fuel:2.3.1")
implementation ("com.squareup.okhttp3:okhttp:4.10.0")
testImplementation(kotlin("test"))
}
使用 Retrofit 在 Kotlin 中创建 HTTP 请求
在使用 Kotlin 或 Java 开发应用程序时,Retrofit 是最常用的库。
在 kotlin 文件夹下,创建一个名为 model 的文件夹。 创建一个名为 Country.kt 的文件,然后将以下代码复制并粘贴到该文件中。
package model
data class Country(var id: Number,
var countryName: String);
这段代码中,我们创建了一个数据类,我们将使用它来存储从服务器获取的国家/地区对象。 该类具有字段 id 和 countryName,它们将映射到从服务器检索到的对象的字段。
在 kotlin 文件夹下,创建一个名为 service 的文件夹。 创建一个名为 CountryService.kt 的文件,然后将以下代码复制并粘贴到该文件中。
package service
import model.Country
import retrofit2.Call
import retrofit2.http.GET
interface CountryService {
@GET("/country/all")
fun getAllCountries(): Call<List<Country>>;
}
在此代码中,我们创建了一个映射到相对路径 /country/all 的 GET 请求,以从服务器获取所有国家 List
请注意,getAllCountries()
方法返回一个 Call,这意味着该方法向服务器发出请求并返回响应。
创建一个名为 CountryServiceImpl.kt 的文件,然后将以下代码复制并粘贴到该文件中。
package service
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class CountryServiceImpl {
fun getCountryServiceFactory(): CountryService{
val retrofit = Retrofit.Builder()
.baseUrl("https://countryapp254.herokuapp.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(CountryService::class.java);
}
}
此类通过将我们在 getAllCountries()
方法中提供的相对 URL 映射到提供给构建器的 baseUrl() 来完成从服务器获取数据的主要工作。
addConverterFactory()
帮助我们使用 Gson 库反序列化 Kotlin 对象,该库也由 Retrofit 提供。
在kotlin文件夹下新建一个Main.kt文件,将以下代码复制粘贴到文件中。
import model.Country
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import service.CountryService
import service.CountryServiceImpl
fun getAllCountriesUsingRetrofit(){
val countryService: CountryService =
CountryServiceImpl().getCountryServiceFactory();
val call: Call<List<Country>> = countryService.getAllCountries();
call.enqueue(object : Callback<List<Country>> {
override fun onResponse(call: Call<List<Country>>,
response: Response<List<Country>>
) {
response.body()?.forEach(::println)
}
override fun onFailure(call: Call<List<Country>>, t: Throwable) {
t.printStackTrace();
}
})
}
fun main(){
getAllCountriesUsingRetrofit();
}
上面的代码验证了我们的 Retrofit 代码是否正常工作。 调用返回 CountryService 的 getCountryServiceFactory()
。
CountryService 实例帮助我们调用 getAllCountries() 方法。 该方法返回一个 Call,其中包含对我们数据的响应。
要获取从服务器检索的国家/地区,请调用 enqueue() 方法并实现 CallBack 的 onResponse() 和 onFailure() 方法。
enqueue() 方法异步执行,因为我们正在创建一个控制台应用程序,所以我们只需要将响应 body() 记录到控制台。 运行此代码并确保输出如下所示。
[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]
使用 Java 标准库的 API 在 Kotlin 中创建 HTTP 请求
在 Main.kt 文件中对前面的示例进行注释,然后将以下代码复制并粘贴到文件中。
import java.net.HttpURLConnection
import java.net.URL
fun getCountriesUsingHttpURLConnection(){
var url = URL("https://countryapp254.herokuapp.com/country/all");
with(url.openConnection() as HttpURLConnection){
inputStream.bufferedReader().use {
it.lines().forEach(::println)
}
}
}
fun main(){
getCountriesUsingHttpURLConnection();
}
URLConnection 是来自 java.net 包的 Java 标准库的一个 API,可以在 Kotlin 中用于发出 HTTP 请求。
HttpURLConnection 是 URLConnection 的一个实例,我们用它来创建到我们服务器的 HTTP 连接。 with() 函数使用已建立的连接向服务器发出单个请求,执行函数内的代码,并返回我们的结果。
函数内的 inputStream 使用 bufferedReader()
从已建立的连接中读取数据,而 use() 扩展函数帮助我们将从服务器读取的数据记录到控制台。 运行此代码并确保输出如下所示。
[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]
使用 Fuel API 在 Kotlin 中创建 HTTP 请求
在 Main.kt 文件中对前面的示例进行注释,然后将以下代码复制并粘贴到文件中。
import com.github.kittinunf.fuel.httpGet
import com.github.kittinunf.result.Result
fun getCountriesUsingFuel(){
val request = "https://countryapp254.herokuapp.com/country/all"
.httpGet()
.responseString{ request, response, result ->
when(result){
is Result.Failure -> {
println(result.getException());
}
is Result.Success -> {
println(result.get())
}
}
}
request.join();
}
fun main(){
getCountriesUsingFuel();
}
Fuel API 是我们可以用来在我们的应用程序中创建 HTTP 请求的另一种方法。 在此示例中,我们调用了 String 类的扩展函数 httpGet() 来指示我们正在发出 GET 请求。
该字符串提供用于从服务器获取数据的 RESTful API。
httpGet()
方法返回一个请求,它允许我们调用 responseString() 方法通过将处理程序作为参数传递到 Charset.UTF-8 中异步执行请求。
该处理程序是一个 lambda 函数,它接受类型为 Request、Response 和 Result 的三个参数并返回一个 Unit,这意味着它不返回任何值。 由于我们对结果感兴趣,因此我们调用 Failure 和 Success,它们分别在应用程序失败或成功时提供结果。
when()
方法和Java中的switch一样,帮助我们在请求成功或失败时做出不同的决定。 运行此代码并确保输出如下所示。
[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]
使用 OkHttp API 在 Kotlin 中创建 HTTP 请求
在 Main.kt 文件中对前面的示例进行注释,然后将以下代码复制并粘贴到文件中。
import okhttp3.OkHttpClient
import okhttp3.Request
private val httpClient = OkHttpClient()
fun getCountriesUsingOkHttp() {
val countriesRequest = Request.Builder()
.url("https://countryapp254.herokuapp.com/country/all")
.build();
httpClient.newCall(countriesRequest).execute().use { countryResponse ->
if (!countryResponse.isSuccessful) throw RuntimeException("status code $countryResponse");
println(countryResponse.body!!.string())
}
}
fun main(){
getCountriesUsingOkHttp();
}
OkHttpClient()
创建一个共享的 API 实例,我们可以使用它向服务器发出 HTTP 请求。
创建共享实例是因为每个客户端都有自己的线程池和连接池,重用它们对于节省内存和减少延迟很重要。
Builder()
使用提供的 URL 创建请求,并准备向服务器发出请求,我们从 OkHttpClient() 实例调用 newCall() 方法并将请求作为该方法的参数传递。
newCall()
方法返回一个 Call,我们调用它的 execute() 方法从 Response.body() 中获取请求的响应。 use() 扩展函数帮助我们访问响应数据并将其记录到控制台。
请注意
,无论是否抛出异常,use() 函数都会关闭结果。 运行此代码并确保输出如下所示。
[{"id":18,"countryName":"Kenya"},
{"id":20,"countryName":"Tanzania"},
{"id":21,"countryName":"Ethiopia"},
{"id":22,"countryName":"Malawi"},
{"id":23,"countryName":"Country"},
{"id":24,"countryName":"Country"},
{"id":25,"countryName":"Kenya"},
{"id":26,"countryName":"Country"},
{"id":27,"countryName":"USA"},
{"id":28,"countryName":"USA"},
{"id":29,"countryName":"Kenya"},
{"id":30,"countryName":"Kenya"}]
总结
在本篇文章中,我们学习了可用于在 Kotlin 中创建 HTTP 请求的不同方法。 我们介绍的方法包括使用 Retrofit、使用 Java 标准库的 API、使用 Fuel API,最后介绍了使用 OkHttp API。
请注意
,这些并不是我们可以使用的唯一方法; 我们可以使用其他方法,例如 Volley API。 随意使用适合您的用例的任何方法。
相关文章
Kotlin 中 Java String[] 的等价物
发布时间:2023/05/13 浏览次数:59 分类:Java
-
本文介绍了 Kotlin 中 Java String[] 的等价物。 我们将看到所有可能的方法来为 Kotlin 实现与 Java 中的 String[] 相同的结果。
将 Java 文件代码转换为 Kotlin
发布时间:2023/05/13 浏览次数:142 分类:Java
-
Kotlin 现在是一种官方的 Android 语言。 因此,您可能希望将 Java 文件更改为 Kotlin。 本文教您如何将 Java 转换为 Kotlin。
在 Kotlin 中使用 forEach
发布时间:2023/05/13 浏览次数:122 分类:Java
-
本文介绍 Kotlin 中 forEach 关键字的概念和使用。 我们将看到一些使用 Kotlin forEach 循环的示例来理解它。
在 Kotlin 中使用 reified 关键字
发布时间:2023/05/13 浏览次数:197 分类:Java
-
reified 关键字是在 Kotlin 中使用泛型时最常使用的编程概念。在本教程中,我们将学习如何使用两种方法解决此问题,包括将类型的类作为泛型函数的参数传递,以及将 reified 关键字与内联函数
Kotlin 中 ! 和 ? 运算符之间的区别
发布时间:2023/05/13 浏览次数:180 分类:Java
-
在 Kotlin 中,断言运算符 !! 和安全调用符 ? 使用 Null 安全。本文介绍空安全的概念。 我们也将通过如何! 和 ? 在 Kotlin 中有助于空安全。
Kotlin 中 is 运算符 与 as 运算符之间的区别
发布时间:2023/05/13 浏览次数:148 分类:Java
-
这篇文章讨论了 Kotlin 中 is 和 as 运算符之间的区别。 我们还将介绍如何以及何时使用每一个。
Android Studio 中的 Kotlin 打印到控制台
发布时间:2023/05/13 浏览次数:52 分类:Java
-
Kotlin 的 logcat 窗口可以实时显示输出,让开发人员能够高效地处理他们的代码。 今天,我们将完成将消息打印到 Kotlin 控制台的步骤。
在 Kotlin 中获取随机数
发布时间:2023/05/13 浏览次数:68 分类:Java
-
随机数是使用一种算法从一组数字中生成的,该算法可确保每个数字的生成概率相等。在Kotlin中使用IntRange的random()扩展函数
在 Kotlin 中使用内联函数
发布时间:2023/05/13 浏览次数:199 分类:Java
-
Kotlin 允许使用内联函数有效地处理更高级的函数。 在本文中,我们将介绍我们需要了解的有关 Kotlin 中的内联函数的所有信息。