You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin构建Elasticsearch HttpClient时出现NoSuchFieldError

问题分析与解决方案

错误原因

  1. Apache HttpClient版本冲突:Android系统内置了旧版Apache Http组件,你项目引入的新版HttpClient库中的SSLConnectionSocketFactory类,会尝试访问AllowAllHostnameVerifier.INSTANCE静态字段,但系统自带的旧版AllowAllHostnameVerifier类无此字段,触发NoSuchFieldError。
  2. 文件路径无效:代码中使用的C:\\gbif_geo.json是Windows系统路径,Android设备无法识别,需替换为Android设备的合法存储路径。

解决方案

方案一:改用Elasticsearch官方Rest Client(推荐)

你已导入Elasticsearch官方客户端依赖,直接用它实现POST操作,规避版本冲突:

import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import co.elastic.clients.elasticsearch.ElasticsearchClient
import co.elastic.clients.json.jackson.JacksonJsonpMapper
import co.elastic.clients.transport.rest_client.RestClientTransport
import org.elasticsearch.client.RestClient
import org.elasticsearch.client.HttpHost
import java.io.File
import java.io.FileInputStream

class MainActivity : AppCompatActivity() {
    private lateinit var t: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        t = findViewById(R.id.textView)
        val btn = findViewById<Button>(R.id.button)

        btn.setOnClickListener {
            sendFileToElasticsearch()
        }
    }

    private fun sendFileToElasticsearch() {
        try {
            // 替换为Android设备内部存储的文件路径
            val jsonFile = File(getFilesDir(), "gbif_geo.json")
            if (!jsonFile.exists()) {
                t.text = "文件不存在"
                return
            }

            // 初始化Elasticsearch客户端
            val restClient = RestClient.builder(HttpHost("192.168.x.x", 9200, "http")).build()
            val transport = RestClientTransport(restClient, JacksonJsonpMapper())
            val client = ElasticsearchClient(transport)

            // 读取文件并执行bulk请求
            val bulkContent = FileInputStream(jsonFile).bufferedReader().readText()
            val response = client.bulk { it.body(bulkContent) }

            t.text = "请求成功: ${response.items().size} 条数据处理完成"
            transport.close()
            restClient.close()
        } catch (e: Exception) {
            t.text = "错误: ${e.message}"
            e.printStackTrace()
        }
    }
}

方案二:修复HttpClient版本冲突

若坚持使用Apache HttpClient,按以下步骤处理:

  1. 配置依赖与冲突排除
    在Module级别的build.gradle中添加:
dependencies {
    implementation 'org.apache.httpcomponents:httpclient-android:4.3.5.1'
}

android {
    useLibrary 'org.apache.http.legacy'
    configurations.all {
        exclude group: 'org.apache.httpcomponents', module: 'httpclient'
    }
}
  1. 修正文件路径
    替换Windows路径为Android合法路径:
// 内部存储路径
val jsonFile = File(getFilesDir(), "gbif_geo.json")
// 或外部存储(需申请权限)
// val jsonFile = File(getExternalFilesDir(null), "gbif_geo.json")
  1. 添加权限
    在AndroidManifest.xml中补充:
<uses-permission android:name="android.permission.INTERNET" />
<!-- 访问外部存储需添加 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

额外注意事项

  • localhost替换:Android模拟器中localhost指向自身,若Elasticsearch运行在电脑上,需替换为电脑局域网IP(如192.168.x.x),同时修改Elasticsearch配置文件elasticsearch.yml,设置network.host: 0.0.0.0允许外部访问。
  • 动态权限申请:Android 6.0及以上访问外部存储时,需在代码中动态申请读写权限。

内容的提问来源于stack exchange,提问作者SCORPIOGA3T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 22:35:12