Изменение значения определенных аннотированных полей объекта, который используется в качестве типа для нескольких полей в некотором объекте — Jackson Object Mapper Сериализовать

#java #json #serialization #jackson #objectmapper

#java #json #сериализация #Джексон #objectmapper

Вопрос:

У меня есть класс Person:

 public class Person {
    private String name;
    private String address;
}
 

Теперь этот класс Person используется в другом классе как:

 public class Group {
    private Person nicePerson;
    private Person badPerson;
    private Person secretPerson;
}
 

Теперь я хочу сериализовать свой групповой объект в JSON с помощью Jackson ObjectMapper. Я использую пользовательский сериализатор, основанный на некоторой аннотации.

Когда я сериализую объект Group, я ищу следующий вывод:

 {
    "nicePerson": {
        "name": "John",
        "address": "usa"
    },
    "badPerson": {
        "name": "Harold",
        "address": "canada"
    },
    "secretPerson": {
        "name": "XXXXXXX",
        "address": "london"
    }
}
 

Здесь я хочу изменить имя ‘secretPerson’ на «XXXXXXX».

Но у меня возникли некоторые проблемы.

Я сделал следующую аннотацию:

 @Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface SecretInfo {
    String maskedValue = "XXXXXXX";
    String value() default maskedValue;
}
 

Я аннотировал свой класс Person следующим образом:

 public class Person {
    @SecretInfo
    private String name;
    private String address;
}
 

Я создал следующий сериализатор, который ищет эту аннотацию, а затем изменяет значение. Теперь для удобства используются некоторые обобщения.

 public class SecretInfoSerializer<T> extends StdSerializer<T> implements ContextualSerializer {

    private SecretInfo secretInfo;

    public SecretInfoSerializer() {
        super((Class<T>) String.class);
    }

    public SecretInfoSerializer(SecretInfo secretInfo,
                                          JavaType clazz) {
        super(clazz);
        this.secretInfo = secretInfo;
    }

    @Override
    public void serialize(T value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        if (secretInfo != null amp;amp; value != null) {
            jsonGenerator.writeString(secretInfo.value());
        } else jsonGenerator.writeString(getValue(value));
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
        if (property != null) {
            return new SecretInfoSerializer<>(
                    property.getAnnotation(SecretInfo.class),
                    property.getType());
        } else {
            return new SecretInfoSerializer<>();
        }
    }

    private String getValue(T value) {
        if (value == null) {
            return "null";
        } else {
            return value.toString();
        }
    }

}
 

Я связал это с аннотацией Introspector и создал ObjectMapper.
Затем я сериализовал свой класс ‘Group’ выше. Но я получаю следующий вывод:

 {
    "nicePerson": {
        "name": "XXXXXXX",
        "address": "usa"
    },
    "badPerson": {
        "name": "XXXXXXX",
        "address": "canada"
    },
    "secretPerson": {
        "name": "XXXXXXX",
        "address": "london"
    }
}
 

Как вы можете видеть, поскольку я аннотировал поле ‘name’ в классе Person, я получаю «XXXXXXX» для каждого существующего класса Person. Но это не то, чего я хотел. Я просто хочу изменить значение только для ‘secretPerson’.

Я не знаю, что делать:

Может быть, есть какой-то способ, например, следующий:

 public class Group {
    private Person nicePerson;
    private Person badPerson;
    @HasSecretInfo
    private Person secretPerson; 
}
 

Затем сериализатор будет проверять, если это @HasSecretInfo так, только затем искать @SecretInfo … и т.д. что-то вроде этого.

Итак, я ищу решение этой проблемы. Если у вас есть какое-либо решение, это было бы здорово.