ES的java客户端中SearchRequest和SearchResponse的序列化和反序列化

Elastcsearch官方提供了一个elasticsearch-rest-high-level-client,作者在写bug的时候需要将其中的ActionRequest(子类包括SearchRequest、IndexRequest、UpdateRequest等)和SearchResponse类分别做序列化和反序列化。

首先,这两个类都没有实现Serializable接口也无法直接用Json工具序列化为Json字符串。但是官方给我们提供了其它方法,亲测有效,以下作为记录:

ActionRequest(使用SearchRequest作例子):

官方提供了readFrom(StreamInput in)和writeTo(StreamOutput out)方法供使用

public abstract class ActionRequest extends TransportRequest {

  ...

    @Override
    public void readFrom(StreamInput in) throws IOException {
        super.readFrom(in);
    }

    @Override
    public void writeTo(StreamOutput out) throws IOException {
        super.writeTo(out);
    }
...
}

所以,我们实现序列化的核心代码如下:


        BytesStreamOutput output = new BytesStreamOutput();
        actionRequest.writeTo(output);
        //用base64进行编码(如果没有这步,反序列化时会失败)
        String s = BaseCoder.encryptBASE64(output.bytes().toBytesRef().bytes);

反序列化:

         //base64解码
        byte[] s1 = BaseCoder.decryptBASE64(s);
        BytesStreamOutput bytesStreamOutput = new BytesStreamOutput();
        bytesStreamOutput.write(s1);

        //设置解析器
        IndicesModule indicesModule = new IndicesModule(Collections.emptyList());
        SearchModule searchModule = new SearchModule(Settings.EMPTY, false, Collections.emptyList());
        List<NamedWriteableRegistry.Entry> entries = new ArrayList<>();
        entries.addAll(indicesModule.getNamedWriteables());
        entries.addAll(searchModule.getNamedWriteables());
        NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry(entries);
        //转换成输入流
        StreamInput in= new
NamedWriteableAwareStreamInput(bytesStreamOutput.bytes().streamInput(), namedWriteableRegistry);
        
        //还原
        SearchRequest request = new SearchRequest();
        actionRequest.readFrom(in);
       

SearchResponse:

作者在对SearchResponse进行序列化处理时发现上面的办法行不通,于是换了一个办法。es给我们提供了json的解决方式(XContent)。

序列化:

 XContentBuilder builder = XContentFactory.jsonBuilder();
        XContentBuilder xContent = searchResponse.toXContent(builder, ToXContent.EMPTY_PARAMS);
        String jsonResponse = xContent.string();

反序列化:

 NamedXContentRegistry namedXContentRegistry = new NamedXContentRegistry(getDefaultNamedXContents());
        XContentParser parser = JsonXContent.jsonXContent.createParser(namedXContentRegistry, jsonResponse);

 SearchResponse response= SearchResponse.fromXContent(parser);
private static List<NamedXContentRegistry.Entry> getDefaultNamedXContents() {
        Map<String, ContextParser<Object, ? extends Aggregation>> map = new HashMap<>();
        //这里设置统计字段(Aggregation)
        map.put(TopHitsAggregationBuilder.NAME, (p, c) -> ParsedTopHits.fromXContent(p, (String) c));
        map.put(DateRangeAggregationBuilder.NAME, (p, c) -> ParsedDateRange.fromXContent(p, (String) c));
        map.put(FilterAggregationBuilder.NAME, (p, c) -> ParsedFilter.fromXContent(p, (String) c));
        map.put(StringTerms.NAME, (p, c) -> ParsedStringTerms.fromXContent(p, (String) c));
        map.put(LongTerms.NAME, (p, c) -> ParsedLongTerms.fromXContent(p, (String) c));
        map.put(DoubleTerms.NAME, (p, c) -> ParsedDoubleTerms.fromXContent(p, (String) c));
        List<NamedXContentRegistry.Entry> entries = map.entrySet().stream()
                .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue()))
                .collect(Collectors.toList());
        SearchModule searchModule = new SearchModule(Settings.EMPTY, false, Collections.EMPTY_LIST);
        //普通字段
        entries.addAll(searchModule.getNamedXContents());
        return entries;
    }

 

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值