Isv*_*rei 17 java elasticsearch
我在这里关注弹性搜索 java api 客户端的教程: https: //www.elastic.co/guide/en/elasticsearch/client/java-api-client/current/connecting.html
我的代码如下。
// Create the low-level client
RestClient restClient = RestClient.builder(
new HttpHost("localhost", 9200)).build();
// Create the transport with a Jackson mapper
ElasticsearchTransport transport = new RestClientTransport(
restClient, new JacksonJsonpMapper());
// And create the API client
ElasticsearchClient client = new ElasticsearchClient(transport);
try {
SearchResponse<Object> search = client.search(s -> s
.index("*:*"),
Object.class);
} catch (IOException e) {
System.out.println(e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)
这段代码抛出以下异常:
co.elastic.clients.transport.TransportException: [es/search] Missing [X-Elastic-Product] header. Please check that you are connecting to an Elasticsearch instance, and that any networking filters are preserving that header.
Run Code Online (Sandbox Code Playgroud)
我尝试通过setDefaultHeaders如下方法手动放置此标头:
RestClientBuilder builder = RestClient.builder(
new HttpHost("localhost", 9200, "http"));
Header[] defaultHeaders = new Header[]{new BasicHeader("X-Elastic-Product", "Elasticsearch")};
builder.setDefaultHeaders(defaultHeaders);
RestClient restClient = builder.build();
Run Code Online (Sandbox Code Playgroud)
但错误是一样的。
我尝试过 7.16 和 8.0.0 版本,结果相同。
mys*_*cks 17
RestClientBuilder允许您指定的默认标头是请求标头,而不是响应标头。您收到的错误是因为较旧的 Elasticsearch [服务器] 版本X-Elastic-Product=Elasticsearch在任何 API 响应中都不包含标头,但最近的发行版包含标头(7.14+?),因此较新版本elasticsearch-java(即客户端)需要它们。
我在同一条船上 \xe2\x80\x94 我使用 8.4.2elasticsearch-java和 Elasticsearch 服务器版本 7.2.0。
我遇到了两个基于格式的兼容性问题:
\nContent-Type向服务器传递未知信息,因此其请求被拒绝并返回 406X-Elastic-Product=Elasticsearch标头幸运的是,RestClientBuilder允许您通过以下方式自定义底层 http 客户端:setHttpClientConfigCallback。回调看起来像这样,所以基本上您可以拦截请求和响应,操作标头,从而解决这些问题:
public interface HttpClientConfigCallback {\n /**\n * Allows to customize the {@link CloseableHttpAsyncClient} being created and used by the {@link RestClient}.\n * Commonly used to customize the default {@link org.apache.http.client.CredentialsProvider} for authentication\n * or the {@link SchemeIOSessionStrategy} for communication through ssl without losing any other useful default\n * value that the {@link RestClientBuilder} internally sets, like connection pooling.\n */\n HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder);\n }\nRun Code Online (Sandbox Code Playgroud)\n具体来说,这对我有用:
\nvar httpClientConfigCallback = httpClientBuilder ->\n httpClientBuilder\n .setDefaultCredentialsProvider(credentialsProvider)\n // this request & response header manipulation helps get around newer (>=7.16) versions\n // of elasticsearch-java client not working with older (<7.14) versions of Elasticsearch\n // server\n .setDefaultHeaders(\n List.of(\n new BasicHeader(\n HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString())))\n .addInterceptorLast(\n (HttpResponseInterceptor)\n (response, context) ->\n response.addHeader("X-Elastic-Product", "Elasticsearch"));\nvar restClient =\n RestClient.builder(elasticsearchHosts)\n .setHttpClientConfigCallback(httpClientConfigCallback)\n .build();\n\nRun Code Online (Sandbox Code Playgroud)\n请注意,上述产品和 API 版本之间仍然可能存在行为差异,因为它们相差太大。以上仅修复了基于格式的不兼容性。因此,最好至少使用这些组件的相同主要版本(即使不是完全相同的版本)。
\n