gpt4 book ai didi

java - @JsonTypeResolver 是使用多个属性解析的唯一选项吗?

转载 作者:搜寻专家 更新时间:2023-11-01 02:42:44 26 4
gpt4 key购买 nike

我有以下格式的传入 JSON 数据

{
"header": {
"schema_id": {
"namespace": "omh",
"name": "physical-activity",
},
},
"body": {
"activity_name": "walking",
"distance": {
"value": 1.5,
"unit": "mi"
},
}
}

和相应的 Java 类看起来像

public class DataPoint<T extends Measure> {

private DataPointHeader header;
private T body;

@JsonNaming(LowerCaseWithUnderscoresStrategy.class)
public class PhysicalActivity extends Measure {

private String activityName;
private LengthUnitValue distance;

我希望 Jackson 根据 JSON 文档中的 schema_idbody 解析为 PhysicalActivity 类型,例如在伪代码中

if schema_id.namespace == 'omh' && schema_id.name == 'physical-activity'
then return PhysicalActivity.class

我已经尝试使用 @JsonTypeIdResolver 执行此操作,但是如果我尝试使用 @JsonTypeInfo 导航到 header.schema_id.name,例如

@JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
property = "header.schema_id.name")
@JsonTypeIdResolver(DataPointTypeIdResolver.class)
public abstract class Measure {

我收到一个missing property: 'header.schema_id.name' 错误。即使可以,我也不认为我可以同时对 namespacename 属性做出决定。

除了使用 @JsonTypeResolver 从头开始​​构建之外,还有其他明智的方法吗?

最佳答案

在 Jackson 的源代码中,似乎有很多类型 ID 是字符串的假设,所以我怀疑 JsonTypeResolver 是一种可行的方法……虽然它看起来并不简单!

至少当您只有“header”和“body”属性时,完全自定义的反序列化器并不太难:

public static class DataPointDeserializer extends StdDeserializer<DataPoint<?>> implements ResolvableDeserializer {
private JsonDeserializer<Object> headerDeserializer;
private Map<SchemaId, JsonDeserializer<Object>> activityDeserializers;

public DataPointDeserializer() {
super(DataPoint.class);
}

@Override
public void resolve(DeserializationContext ctxt) throws JsonMappingException {
headerDeserializer = ctxt.findRootValueDeserializer(ctxt.getTypeFactory().constructType(
DataPointHeader.class));
activityDeserializers = new HashMap<>();
activityDeserializers.put(new SchemaId("omh", "physical-activity"),
ctxt.findRootValueDeserializer(ctxt.getTypeFactory().constructType(PhysicalActivity.class)));
}

@Override
public DataPoint<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException,
JsonProcessingException {
String fieldName = p.nextFieldName();
if (fieldName == null)
throw ctxt.wrongTokenException(p, JsonToken.FIELD_NAME, "expected 'header' and 'body' fields");
if (fieldName.equals("header")) {
p.nextToken();
DataPointHeader header = (DataPointHeader) headerDeserializer.deserialize(p, ctxt);
JsonDeserializer<Object> bodyDeserializer = activityDeserializers.get(header.schemaId);
if (bodyDeserializer == null) throw ctxt.mappingException("No mapping for schema: " + header.schemaId);
fieldName = p.nextFieldName();
if (fieldName == null)
throw ctxt.wrongTokenException(p, JsonToken.FIELD_NAME, "expected 'body' field after header");
p.nextToken();
Measure body = (Measure) bodyDeserializer.deserialize(p, ctxt);
DataPoint<Measure> dataPoint = new DataPoint<>();
dataPoint.header = header;
dataPoint.body = body;
return dataPoint;
}
else if (fieldName.equals("body")) {
p.nextToken();
try (TokenBuffer tb = new TokenBuffer(p)) {
tb.copyCurrentStructure(p);
fieldName = p.nextFieldName();
if (fieldName == null)
throw ctxt.wrongTokenException(p, JsonToken.FIELD_NAME, "expected 'header' field after body");
if (!fieldName.equals("header"))
throw ctxt.weirdStringException(fieldName, DataPoint.class, "Unexpected field name");
p.nextToken();
DataPointHeader header = (DataPointHeader) headerDeserializer.deserialize(p, ctxt);
JsonDeserializer<Object> bodyDeserializer = activityDeserializers.get(header.schemaId);
if (bodyDeserializer == null)
throw ctxt.mappingException("No mapping for schema: " + header.schemaId);
JsonParser bodyParser = tb.asParser();
bodyParser.nextToken();
Measure body = (Measure) bodyDeserializer.deserialize(bodyParser, ctxt);
DataPoint<Measure> dataPoint = new DataPoint<>();
dataPoint.header = header;
dataPoint.body = body;
return dataPoint;
}
}
else throw ctxt.weirdStringException(fieldName, DataPoint.class, "Unexpected field name");
}
}

关于java - @JsonTypeResolver 是使用多个属性解析的唯一选项吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30060617/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com