Существует ли пользовательский шаблон Json Serializer для сериализации свойства по-разному, включая имя ключа свойства? - PullRequest
1 голос
/ 21 апреля 2020

У меня есть класс, который нужно сериализовать

public class Abc
{
 private long age;
 private JaxBElement<Foo> fooWrapper;
 // other properties
}

Ожидаемый вывод JSON равен

{
 "age": 24,
 "my_own_key": "my_own_value" // the key should not be "fooWrapper"

Ограничение состоит в том, что исходный класс Ab c не может быть изменен, поскольку он генерируется из xj c, и я пока не хочу исследовать пользовательский класс с использованием привязок.

Я пробовал собственные сериализаторы, модификаторы bean et c. для JaxBElement и все они позволяют мне контролировать сериализацию. Но они работают только на VALUE собственности. Они не позволяют мне что-то менять на уровне " KEY -VALUE". Это суть вопроса. Ключ уже выписан для свойства до вызова настраиваемого сериализатора для управления значением.

Например, мой настраиваемый сериализатор вызывается только после того, как система Джексона выпустила ключ

 "fooWrapper": // now for the value part, let me invoke the custom serializer 

Таким образом, вывод JSON всегда содержит ключ "fooWrapper".

{ "fooWrapper": { "any-key": "any-value" } }
// the fooWrapper is already emitted out. That is what needs to be controlled.

Я прошу контролировать сериализацию на более высоком уровне, чтобы можно было контролировать и ключ, и значение. Поэтому, когда класс Ab c сериализуется, свойство fooWrapper вообще не должно быть записано как ключ, и должен вызываться какой-либо пользовательский сериализатор.

Другое ограничение заключается в том, что существует несколько классов, таких как Ab c который может иметь такой JaxBElement. Это не известно заранее. Таким образом, должен быть универсальный c способ присоединения пользовательского сериализатора.

Псевдопросмотр действительно, что мы можем присоединить пользовательский сериализатор к любому классу, у которого есть свойство, которое соответствует шаблону так, чтобы Сериализатор может управлять именем записанного свойства (или всего большого двоичного объекта).

Кроме того, проблема сама по себе не задается c для JaxBElement. Это может быть любая собственность. Проблема скорее в контролируемой сериализации, ВКЛЮЧАЯ записываемый ключ.

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Если вы хотите контролировать сериализацию пары key-value, вам необходимо зарегистрировать пользовательский сериализатор не только для JaxBElement<Foo> fooWrapper, но и для класса Abc, чтобы изменить значение key.

Поскольку оно не универсальное c решение, вы также можете попытаться создать MixIn класс или интерфейс и предоставить дополнительную конфигурацию:

interface MixInA {

    @JsonSerialize(using = JAXBElementJsonSerializer.class)
    @JsonProperty("newProperty")
    JAXBElement<Foo> getFooWrapper();
}

См. также:

Недостатком этого решения является необходимость найти все типы, для которых вы должны зарегистрировать MixIn класс или интерфейс. В случае, если поля различны, вам нужно создать много разных getters или много разных MixIn интерфейсов, чтобы покрыть их все.

Так что, вероятно, наиболее гибким решением будет реализация пользовательских com.fasterxml.jackson.databind.AnnotationIntrospector и для заданных типа вы можете вернуть пользовательский сериализатор и пользовательское имя. Простой пример:

class DynamicJaxbAnnotationIntrospector extends AnnotationIntrospector {

    @Override
    public Version version() {
        return new Version(1, 0, 0, "Dynamic JaxbElement", "your.package", "jackson.dynamic.jaxb");
    }

    @Override
    public Object findSerializer(Annotated am) {
        if (am.getRawType() == JAXBElement.class) {
            return new JAXBElementJsonSerializer();
        }
        return super.findSerializer(am);
    }

    @Override
    public PropertyName findNameForSerialization(Annotated a) {
        if (a.getRawType() == JAXBElement.class) {
            return new PropertyName("newProperty");
        }
        return super.findNameForSerialization(a);
    }
}

См. Также статью ниже, как его использовать:

0 голосов
/ 21 апреля 2020

Возможно, вы просто используете неверный вид сериализатора. Этот пост , хотя немного устаревший, должен показать вам, как делать то, что вы хотите с StdSerializer.

Этот тип сериализатора позволяет вам контролировать и ключ, и значение.

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