Elasticsearch 7.4客户端Profile数据解析溢出问题求助
Elasticsearch 7.4客户端Profile字段反序列化溢出问题解决办法
问题核心:返回的process字段值2487313600是秒级时间戳,超出Java Integer最大值(2147483647),而官方SearchResponse中对应字段为Integer类型。单纯开启DeserializationFeature.USE_LONG_FOR_INTS无效,因为Elasticsearch客户端使用独立的序列化机制,不直接继承全局ObjectMapper配置。
以下是可行解决方案:
方案一:自定义Profile类替换默认类型
- 新建自定义Profile类,将
process字段类型改为Long,其余字段与官方类保持一致:
public class CustomProfile { private Long process; // 复制官方Profile类的其他字段,添加对应的getter、setter方法 }
- 配置客户端时,通过Jackson MixIn机制将官方Profile类映射到自定义类:
ElasticsearchClient client = new ElasticsearchClient( RestClient.builder(new HttpHost("localhost", 9200)), new JacksonJsonpMapper(objectMapper -> { objectMapper.addMixIn(Profile.class, CustomProfile.class); objectMapper.enable(DeserializationFeature.USE_LONG_FOR_INTS); }) );
方案二:在Elasticsearch查询时转换为毫秒级时间戳
- 修改查询DSL,通过脚本字段将
process的秒级时间戳转为毫秒级,避免客户端序列化溢出:
{ "query": {"match_all": {}}, "profile": true, "script_fields": { "process_millis": { "script": { "source": "doc['process'].value * 1000" } } } }
- 客户端直接接收
process_millis字段,类型设为Long即可。
方案三:注册自定义Jackson反序列化器
- 针对
process字段编写专属反序列化器,强制解析为Long类型:
public class ProcessDeserializer extends JsonDeserializer<Long> { @Override public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { return Long.parseLong(p.getText()); } }
- 将反序列化器注册到客户端的Jackson映射器中:
SimpleModule module = new SimpleModule(); module.addDeserializer(Long.class, new ProcessDeserializer()); JacksonJsonpMapper mapper = new JacksonJsonpMapper(); mapper.objectMapper().registerModule(module); mapper.objectMapper().enable(DeserializationFeature.USE_LONG_FOR_INTS); ElasticsearchClient client = new ElasticsearchClient(RestClient.builder(...), mapper);
内容的提问来源于stack exchange,提问作者MangeshShinde
相关产品推荐
相关产品推荐

