如何将含raw嵌套的Elasticsearch JSON响应映射到Java实体类
解决Jackson映射Elasticsearch嵌套raw字段到平Java类的问题
方法一:自定义通用反序列化器
编写通用反序列化器,自动提取嵌套对象里的raw字段值,适配不同数据类型:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; public class RawValueDeserializer<T> extends JsonDeserializer<T> { @Override public T deserialize(JsonParser parser, DeserializationContext context) throws IOException { JsonNode node = parser.getCodec().readTree(parser); JsonNode rawNode = node.get("raw"); if (rawNode == null) { return null; } return context.readValue(rawNode.traverse(parser.getCodec()), (Class<T>) context.getContextualType().getRawClass()); } }
在目标Java类的字段上添加@JsonDeserialize注解指定反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; public class MyClass { @JsonDeserialize(using = RawValueDeserializer.class) private String name; @JsonDeserialize(using = RawValueDeserializer.class) private Double number; // 生成标准getter、setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getNumber() { return number; } public void setNumber(Double number) { this.number = number; } }
之后即可按预期调用Jackson解析:
ObjectMapper objectMapper = new ObjectMapper(); MyClass jsonParsed = objectMapper.readValue(json, MyClass.class);
方法二:嵌套类配合属性映射
不想写自定义反序列化器的话,可以用内部嵌套类承接Elasticsearch的嵌套结构,再对外暴露平级的取值方法:
public class MyClass { @JsonProperty("name") private RawValue<String> nameWrapper; @JsonProperty("number") private RawValue<Double> numberWrapper; // 对外直接返回raw值的getter public String getName() { return nameWrapper != null ? nameWrapper.raw : null; } public Double getNumber() { return numberWrapper != null ? numberWrapper.raw : null; } // 内部嵌套类,对应Elasticsearch的raw结构 private static class RawValue<T> { private T raw; // 生成getter、setter public T getRaw() { return raw; } public void setRaw(T raw) { this.raw = raw; } } }
方法三:全局配置反序列化器(批量处理)
如果项目中有大量类需要处理相同的raw嵌套结构,可以将反序列化器注册到ObjectMapper全局生效:
import com.fasterxml.jackson.databind.module.SimpleModule; ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); // 为需要处理的类型注册反序列化器 module.addDeserializer(String.class, new RawValueDeserializer<>()); module.addDeserializer(Double.class, new RawValueDeserializer<>()); objectMapper.registerModule(module); // 直接解析即可,无需在类上添加注解 MyClass jsonParsed = objectMapper.readValue(json, MyClass.class);
内容的提问来源于stack exchange,提问作者Diego Sanz
相关产品推荐
相关产品推荐

