elasticsearch-java:8.15.0调用hotThreads方法抛出TransportException问题
问题解决:调用Elasticsearch hot_threads API抛出text/plain格式异常
异常原因
Elasticsearch的nodes.hot_threads API默认返回text/plain格式响应,但你配置的SimpleJsonpMapper仅支持解析JSON格式数据,因此触发了TransportException。
解决方案
方案1:强制API返回JSON格式(推荐)
修改业务代码,调用hotThreads时显式指定返回格式为JSON,让客户端能正常解析:
@Slf4j @Service @RequiredArgsConstructor public class NodeHealthService { private final ElasticsearchClient elasticsearchClient; public HotThreadsResponse hotThreads() throws Exception { // 添加format参数指定返回JSON格式 return elasticsearchClient.nodes().hotThreads(request -> request.format("json")); } }
方案2:自定义Mapper兼容text/plain响应
如果无法修改请求参数,可自定义JsonpMapper使其支持解析text/plain格式响应。修改ElasticJavaClientConfig中的elasticsearchClient Bean:
@Bean public ElasticsearchClient elasticsearchClient(RestClient restClient) { JsonpMapper customMapper = new SimpleJsonpMapper() { @Override public <T> T deserialize(HttpResponse response, Class<T> clazz, JsonpDeserializer<T> deserializer) throws IOException { Header contentTypeHeader = response.getFirstHeader("Content-Type"); if (contentTypeHeader != null && contentTypeHeader.getValue().startsWith("text/plain")) { // 将hot_threads的文本响应封装为JSON结构 String plainText = EntityUtils.toString(response.getEntity()); String json = "{\"hotThreads\": \"" + plainText.replace("\"", "\\\"").replace("\n", "\\n") + "\"}"; // 构造模拟JSON响应供父类解析 HttpResponse mockResponse = new BasicHttpResponse(response.getStatusLine()); mockResponse.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON)); return super.deserialize(mockResponse, clazz, deserializer); } return super.deserialize(response, clazz, deserializer); } }; ElasticsearchTransport transport = new RestClientTransport(restClient, customMapper); return new ElasticsearchClient(transport); }
说明:方案2需要手动处理文本到JSON的转换,逻辑相对复杂,优先推荐方案1。
验证
修改后重新调用hotThreads方法,Elasticsearch将返回JSON格式响应,客户端可正常解析为HotThreadsResponse对象。
内容的提问来源于stack exchange,提问作者korjun1993
相关产品推荐
相关产品推荐

