如何将Python的HTTP GET登录请求代码转换为Kotlin实现?
问题描述
我原本有一个Python应用,现正迁移至Kotlin。我在Python中有一行处理请求的代码,花费7小时仍未找到在Kotlin中简单发送请求并处理响应的方法,希望有人能给出将这段Python代码转换为Kotlin的示例。
我的Python代码用于发送携带两个参数的GET请求,获取JSON格式响应,后端服务器采用Flask(Python)搭建:
response = requests.get(BASE + "Login/1", {"Name": Name, "Password": Password})
我尝试使用Retrofit编写了一段Kotlin代码,但未能成功,相关代码如下:
fun LoginServer(): Response<ResponseBody> { // Create Retrofit instance val retrofit = Retrofit.Builder() .baseUrl(BASE) .addConverterFactory(GsonConverterFactory.create()) .build() // Create API client val apiClient = retrofit.create(MyApi::class.java) print("kek") // Make the request val loginName = findViewById<EditText>(R.id.loginName) val loginPasswort = findViewById<EditText>(R.id.loginPasswort) val response = apiClient.login(1, loginName.text.toString(), loginPasswort.text.toString()); return response }
解决方案
1. 先明确Python请求逻辑
你的Python代码是发送GET请求到BASE + "Login/1",并将Name和Password自动转为URL查询参数(requests.get的字典参数默认会做这个转换)。
2. 修正Retrofit实现
第一步:添加依赖
在模块级build.gradle中引入必要依赖:
dependencies { // Retrofit核心库 implementation 'com.squareup.retrofit2:retrofit:2.9.0' // Gson转换器(解析JSON响应) implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // 协程适配器(支持异步请求) implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2' }
第二步:定义正确的API接口
MyApi接口需要严格匹配后端的请求路径和参数规则:
interface MyApi { // {id}对应URL中的Login/1,@Query定义查询参数 @GET("Login/{id}") suspend fun login( @Path("id") id: Int, @Query("Name") name: String, @Query("Password") password: String ): Response<ResponseBody> // 若后端返回固定结构的JSON,可自定义数据类替换ResponseBody,方便直接解析 }
第三步:修正请求调用逻辑
Android主线程禁止执行网络请求,必须用协程异步处理,同时避免重复创建Retrofit实例(建议全局单例):
// 全局单例Retrofit(可放在Application类或单独的单例工具类中) private val retrofit = Retrofit.Builder() .baseUrl(BASE) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(CoroutineCallAdapterFactory()) .build() private val apiClient = retrofit.create(MyApi::class.java) // 在Activity/Fragment中调用的方法 fun loginServer() { val loginName = findViewById<EditText>(R.id.loginName).text.toString() val loginPassword = findViewById<EditText>(R.id.loginPasswort).text.toString() // 用生命周期协程异步执行请求 lifecycleScope.launch { try { val response = apiClient.login(1, loginName, loginPassword) if (response.isSuccessful) { // 请求成功,处理响应内容 val jsonContent = response.body()?.string() // 解析JSON或直接使用内容 } else { // 请求失败,处理错误信息 val errorMsg = response.errorBody()?.string() } } catch (e: Exception) { // 处理网络异常(无网络、超时等) e.printStackTrace() } } }
3. 简化方案:用OkHttp直接发送请求
如果觉得Retrofit过于繁琐,可直接用OkHttp实现:
// 先添加OkHttp依赖 // implementation 'com.squareup.okhttp3:okhttp:4.10.0' fun loginWithOkHttp() { val loginName = findViewById<EditText>(R.id.loginName).text.toString() val loginPassword = findViewById<EditText>(R.id.loginPasswort).text.toString() val url = "${BASE}Login/1?Name=${loginName}&Password=${loginPassword}" val client = OkHttpClient() val request = Request.Builder() .url(url) .build() // 异步执行请求 client.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { // 处理请求失败 e.printStackTrace() } override fun onResponse(call: Call, response: Response) { response.use { if (!it.isSuccessful) throw IOException("请求失败:$it") // 获取响应内容 val jsonContent = it.body?.string() // 若需更新UI,切回主线程 runOnUiThread { // 执行UI更新逻辑 } } } }) }
内容的提问来源于stack exchange,提问作者Deimos
相关产品推荐
相关产品推荐

