如何验证我没有收到@JsonProperty 和@JsonAlias 中定义的两个值?
Posted
技术标签:
【中文标题】如何验证我没有收到@JsonProperty 和@JsonAlias 中定义的两个值?【英文标题】:How to validate that I don't receive both values defined in @JsonProperty and @JsonAlias? 【发布时间】:2019-05-26 18:38:03 【问题描述】:我将实体与孩子呈现为数字child_entity_id。但有时我必须处理 child_entity_selector json 对象,而不是 child_entity_id。用于通过数据库中的某些值提取实体。
父实体有这样的注解
@Entity
class Parent
@Id
long id;
@JsonDeserialize(using = EntityReferenceDeserializer.class)
@JsonSerialize(using = EntityReferenceSerializer.class)
@JsonProperty("child_entity_id")
@JsonAlias("child_entity_selector")
Child child;
对于响应json之类的
"id" : 1,
"child_entity_id": 1,
"child_entity_selector":
"child_name": "I am a child"
,
应该抛出异常,因为只有“child_entity_id”或“child_entity_selector”必须同时在一个json中。
当我收到这样的 json 时,它会正确解析,但我的反序列化器同时处理 child_entity_id 和 child_entity_selector,最后一个保留在结果中。
目前我正在尝试同时获取源 json 和实体,以检查 json 是否没有被别名覆盖的重复引用。
我已经设置了一个 SimpleModule 和自定义反序列化器
@Component
public class WebConfig
@Bean
public SimpleModule simpleModule()
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier()
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
if (beanDesc.getBeanClass() == Child.class)
return new ChildDeserializer(deserializer);
return deserializer;
);
return module;
和反序列化器
public class ChildDeserializer extends StdDeserializer<Child> implements ResolvableDeserializer
private final JsonDeserializer<?> defaultDeserializer;
public ChildDeserializer(JsonDeserializer<?> defaultDeserializer)
super(Child.class);
this.defaultDeserializer = defaultDeserializer;
@Override
public Child deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException
Child modelExecution = (Child) defaultDeserializer.deserialize(p, ctxt);
// Can not correctly read raw json after parsing -- node becomes null now after deserialization above
JsonNode node = p.getCodec().readTree(p);
boolean duplication = node.has("child_entity_id") && node.has("child_entity_selector");
if (duplication)
throw new RuntimeException("Duplicated!")
else
log("Not duplicated");
return child;
@Override
public void resolve(DeserializationContext ctxt) throws JsonMappingException
((ResolvableDeserializer) defaultDeserializer).resolve(ctxt);
反序列化后,我无法访问 JsonNode 值。反之,解析JsonNode值后无法获得反序列化的Child实体。
预期的行为
"id" : 1,
"child_entity_id": 1,
和
"id" : 1,
"child_entity_selector":
"child_name": "I am a child"
,
是正确解析的实体。
但在两个参考文献中
"id" : 1,
"child_entity_id": 1,
"child_entity_selector":
"child_name": "I am a child"
,
应该抛出异常。
【问题讨论】:
Only "child_entity_id" or "child_entity_id" is supposed to be presented in one json
很难理解你的意思
@BSeitkazin 改写了它
【参考方案1】:
您可以在 Parent 类中使用 @JsonCreator
处理它
@JsonCreator
public Parent(@JsonProperty("child_entity_id") Child childFromId, @JsonProperty("child_entity_selector") Child childFromSelector)
if (childFromId != null && childFromSelector != null)
throw new RuntimeException("Duplicated!");
this.child = (childFromSelector == null) ? childFromId : childFromSelector;
如果您还需要检查重复字段,有一个JsonParser.Feature.STRICT_DUPLICATE_DETECTION
:
"id" : 1,
"child_entity_id": 1,
"child_entity_id": 2
不幸的是,它不适用于别名
【讨论】:
是的,它可以根据需要在实体创建中工作。但是,由于 objectMapper.readerForUpdating 导致更新操作失败,出现异常“PatchUpdateException details: No fallback setter/field defined for creator property 'child_entity_ref' (through reference chain: Parent[\"child_entity_ref\"])” 我没有使用更新,听起来@JsonAlias
被忽略了。您可以尝试两个设置子字段的设置器,一个标有@JsonProperty("child_entity_id")
,另一个标有@JsonProperty("child_entity_selector")
。不过听起来有点邋遢,而且它不会检测到重复项。
当我同时拥有原始 json 和实体类型时,理想的方法是在反序列化时修改 json。从实体类中,我可以提取带有注释的文件并验证|修改实体以上是关于如何验证我没有收到@JsonProperty 和@JsonAlias 中定义的两个值?的主要内容,如果未能解决你的问题,请参考以下文章
@JsonProperty @JsonIgnoreProperties
如何在使用自动映射器时将属性名称的 jsonproperty 设置为 dto?
序列化json时如何忽略JsonProperty(PropertyName = "someName")?