Elastic Java Client:如何自定义JsonpMapper及用Fastjson替换JacksonJsonpMapper(ES7.16.2)
在Elasticsearch 7.16.2中自定义Elastic Java Client的JsonpMapper
一、自定义JsonpMapper的通用流程
JsonpMapper是Elastic Java Client用于对象与JSON互转的核心接口,默认实现为JacksonJsonpMapper。自定义它的通用步骤如下:
- 实现/扩展JsonpMapper接口:
你可以直接实现JsonpMapper接口,不过更高效的方式是继承AbstractJsonpMapper抽象类——它已经实现了大部分通用逻辑,只需重写序列化、反序列化的核心方法即可。 - 配置客户端使用自定义Mapper:
在构建ElasticsearchClient时,通过ElasticsearchClient.Builder的jsonpMapper()方法传入自定义的实现类实例。
二、用Fastjson替换默认JacksonJsonpMapper的具体实现
由于Fastjson没有官方提供JsonpMapper的实现,我们需要自行封装Fastjson的序列化逻辑,步骤如下:
1. 引入Fastjson依赖
如果使用Maven,在pom.xml中添加:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> </dependency>
Gradle则添加:
implementation 'com.alibaba:fastjson:1.2.83'
2. 实现FastjsonJsonpMapper类
继承AbstractJsonpMapper,封装Fastjson的序列化/反序列化逻辑,同时处理Elasticsearch特定类型(如日期、GeoPoint)的自定义转换:
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.serializer.SerializerFeature; import org.elasticsearch.client.json.AbstractJsonpMapper; import org.elasticsearch.client.json.JsonpParser; import org.elasticsearch.client.json.JsonpSerializable; import org.elasticsearch.client.json.JsonpSerializer; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Type; public class FastjsonJsonpMapper extends AbstractJsonpMapper { private final SerializerFeature[] serializerFeatures = { SerializerFeature.WriteDateUseDateFormat, SerializerFeature.DisableCircularReferenceDetect }; private final Feature[] parserFeatures = { Feature.SupportAutoType }; @Override public <T> T deserialize(JsonpParser parser, Type type) throws IOException { try (InputStream is = parser.inputStream()) { return JSON.parseObject(is, type, parserFeatures); } } @Override public void serialize(JsonpSerializable value, JsonpSerializer serializer, OutputStream out) throws IOException { if (value != null) { if (serializer != null) { serializer.serialize(value, this, out); } else { JSON.writeJSONString(out, value, serializerFeatures); } } } @Override public AbstractJsonpMapper withAttribute(String key, Object value) { FastjsonJsonpMapper mapper = new FastjsonJsonpMapper(); mapper.attributes.putAll(this.attributes); mapper.attributes.put(key, value); return mapper; } }
注意:如果需要处理Elasticsearch的特殊类型(如
GeoPoint、Instant),可以为Fastjson添加对应的ObjectSerializer和ObjectDeserializer,并在构造方法中注册。
3. 配置ElasticsearchClient使用自定义Mapper
构建客户端时,传入FastjsonJsonpMapper实例:
import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.transport.ElasticsearchTransport; import org.elasticsearch.client.transport.rest_client.RestClientTransport; import org.elasticsearch.client.ElasticsearchClient; public class ElasticClientFactory { public static ElasticsearchClient createClient() { RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200, "http")).build(); FastjsonJsonpMapper customMapper = new FastjsonJsonpMapper(); ElasticsearchTransport transport = new RestClientTransport(restClient, customMapper); return new ElasticsearchClient(transport); } }
三、验证替换效果
可以通过简单的文档CRUD操作验证是否生效:
import java.io.IOException; public class TestClient { public static void main(String[] args) throws IOException { ElasticsearchClient client = ElasticClientFactory.createClient(); // 创建测试文档 User user = new User("robin", 30); client.index(i -> i.index("users").id("1").document(user)); // 查询文档并反序列化 User fetchedUser = client.get(g -> g.index("users").id("1"), User.class); System.out.println(fetchedUser); } static class User { private String name; private Integer age; // 构造方法、getter、setter省略 @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } } }
内容的提问来源于stack exchange,提问作者robin z
相关产品推荐
相关产品推荐

