Как проверить, что я не получаю оба значения, определенные в @JsonProperty и @JsonAlias? - PullRequest
0 голосов
/ 29 декабря 2018

Я беру сущность с дочерним элементом, представленным как числовое значение child_entity_id .Но иногда вместо child_entity_id мне приходится обрабатывать child_entity_selector объект json.Который отправляется для извлечения сущности по некоторым значениям из базы данных.

Родительская сущность имеет такие аннотации

@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, так и entity, чтобы убедиться, что 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 невозможно получить десериализованную дочернюю сущность.

Ожидаемое поведение на

{
    "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"
    },
}

должно быть выдано исключение.

1 Ответ

0 голосов
/ 29 декабря 2018

Вы можете обработать его с помощью @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    
}

К сожалению, это не работает с псевдонимами

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...