如何使用Kotlin为Python API指定参数?登录数据传输异常问题
问题分析
你当前的问题是Kotlin端把用户名、密码放在HTTP请求头中传递,但Python API是从请求体(data对象)中读取这些字段,两边数据传递的位置不匹配,导致API无法获取到参数。
解决方案
根据Python API的data.get()用法,通常对应两种常见的请求体格式:表单数据(application/x-www-form-urlencoded)或JSON数据(application/json),以下分别给出适配的Kotlin实现:
方案1:发送表单格式数据(适配Python读取表单请求)
如果你的Python API是从表单数据中读取(比如Flask的request.form),修改Kotlin代码如下:
private fun sendData(username: String, password: String): Thread { return Thread { try { val url = URL("https://127.0.0.1:5000/login") val connection = url.openConnection() as HttpsURLConnection // 设置请求方法为POST,用于提交数据 connection.requestMethod = "POST" // 允许向服务器输出请求体数据 connection.doOutput = true // 声明表单数据的Content-Type connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") // 构建URL编码的表单数据字符串 val postData = "username=${URLEncoder.encode(username, "UTF-8")}&password=${URLEncoder.encode(password, "UTF-8")}" // 将数据写入请求体 val outputStream = connection.outputStream outputStream.write(postData.toByteArray(Charsets.UTF_8)) outputStream.flush() outputStream.close() // 处理服务器响应 if (connection.responseCode == 200) { // 读取响应文本(不要直接打印InputStream对象) val reader = BufferedReader(InputStreamReader(connection.inputStream)) val response = reader.readText() reader.close() println("响应内容:$response") // 切换到UI线程显示Toast runOnUiThread { Toast.makeText(applicationContext, "登录成功", Toast.LENGTH_SHORT).show() } } else { runOnUiThread { Toast.makeText(applicationContext, "请求失败,状态码:${connection.responseCode}", Toast.LENGTH_SHORT).show() } } } catch (e: Exception) { e.printStackTrace() runOnUiThread { Toast.makeText(applicationContext, "请求出错:${e.message}", Toast.LENGTH_SHORT).show() } } } }
方案2:发送JSON格式数据(适配Python读取JSON请求)
如果你的Python API是从JSON请求体中读取(比如Flask的request.get_json()),修改Kotlin代码如下:
private fun sendData(username: String, password: String): Thread { return Thread { try { val url = URL("https://127.0.0.1:5000/login") val connection = url.openConnection() as HttpsURLConnection connection.requestMethod = "POST" connection.doOutput = true // 声明JSON数据的Content-Type connection.setRequestProperty("Content-Type", "application/json") // 构建JSON格式的请求体字符串 val jsonData = """{"username":"$username","password":"$password"}""" val outputStream = connection.outputStream outputStream.write(jsonData.toByteArray(Charsets.UTF_8)) outputStream.flush() outputStream.close() // 处理服务器响应 if (connection.responseCode == 200) { val reader = BufferedReader(InputStreamReader(connection.inputStream)) val response = reader.readText() reader.close() println("响应内容:$response") runOnUiThread { Toast.makeText(applicationContext, "登录成功", Toast.LENGTH_SHORT).show() } } else { runOnUiThread { Toast.makeText(applicationContext, "请求失败,状态码:${connection.responseCode}", Toast.LENGTH_SHORT).show() } } } catch (e: Exception) { e.printStackTrace() runOnUiThread { Toast.makeText(applicationContext, "请求出错:${e.message}", Toast.LENGTH_SHORT).show() } } } }
额外注意事项
- Python端适配:确保你的Python API正确解析请求体:
- 若用表单格式,需从
request.form获取字段:username = request.form.get('username') - 若用JSON格式,需先解析JSON:
data = request.get_json(),再从data中读取字段
- 若用表单格式,需从
- UI线程限制:Android中不能在子线程直接调用
Toast,必须通过runOnUiThread切换到UI线程执行 - 本地测试地址:如果用Android真机测试,
127.0.0.1无法访问本地Python服务,需替换为电脑的局域网IP(如192.168.x.x);若用模拟器,可替换为10.0.2.2 - 异常处理:代码中添加了异常捕获逻辑,避免程序崩溃,同时方便排查请求错误
内容的提问来源于stack exchange,提问作者Jeeves
相关产品推荐
相关产品推荐

